[ANN] php sdk 2.3.0

Hi everyone, I glad to introduce you new release of PHP SDK.

This release contains internal improvements, as well as new features. Note, that minimum version of libcouchbase required is 2.7.2. This release does not depend on PCS extension anymore. Also all classes, which were previously written in PHP, now implemented Zend C APIs, so do not require extra evaluation on module load or request initialization.

New features

Fixed Issues

  • PCBC-443: PCS dependency has been removed and all classes rewritten using Zend C API

Breaking change

Previously if you are using default transcoders, their options were defined in global variables $COUCHBASE_DEFAULT_ENCOPTS and $COUCHBASE_DEFAULT_DECOPTS, so if you were tuning that defaults, now you should do that through INI variables couchbase.encoder.* and couchbase.decoder.*. Full list of supported INI options with detailed description see at API documentation.

Downloads: https://developer.couchbase.com/server/other-products/release-notes-archives/php-sdk
Issue Tracker: https://issues.couchbase.com/projects/PCBC
Source code: https://github.com/couchbase/php-couchbase

Your feedback and contributions are always welcome!

Homebrew formula will be soon merged: https://github.com/Homebrew/homebrew-php/pull/4026

1 Like

Thanks for the update! Especially the API documentation improvements are a big step forward for productivity.

From static code analysis against our Couchbase wrapper codebase I found some other minor breaking changes for us. As we didn’t install the SDK yet, I have no idea if the stubs reflect reality here:

  • _CouchbaseDefaultViewQuery doesn’t exist (or isn’t documented) any more. It probably was never intended for public use as indicated by the leading underscore, but previously was documented as return type for CouchbaseViewQuery::from(), so it is used by our wrapper code.
  • _CouchbaseDefaultViewQuery::group_level() has no documented equivalent any more.
  • CouchbaseViewQuery::stale() doesn’t exist (or isn’t documented) any more. New name which is more consistent with other classes: CouchbaseViewQuery::consistency()
  • CouchbaseBucketManager::getDesignDocuments() now obviously is CouchbaseBucketManager::listDesignDocuments()
  • The constructor for CouchbaseN1qlQuery is now obviously private. Before it implicitly was public.
  • The previously public property CouchbaseN1qlQuery::$options was already marked as “internal” before. Now it doesn’t exist (or isn’t documented) any more.

I also found some probable glitches in the stubs.

  • The documented return type for CouchbaseBucket::remove(), CouchbaseBucket::upsert() and probably others is \Couchbase\Document. I suppose it is \Couchbase\Document[] when we pass an array of IDs?
  • MutationState::from() has no documented return type. PhpStorm interprets that as void, but probably the method still returns MutationState
  • BucketManager::insertDesignDocument() has no documented return type. PhpStorm interprets that as void, but probably the method still returns something.
1 Like

Yes. you right, it was not part of the public interface, but now \Couchbase\ViewQuery supports the same set of methods

But it is still accessible. I didn’t found a good way how to document method alias. I’m going to deprecate this method and in favor groupLevel() as all other snake-cased methods. (same for id_range->idRange)

Correct. It is renamed to consistency(), but old name still works as alias, but will be eventually deprecated.

if you know better way to document method aliases, I will update stubs.

again, that is also true, and the now I’m looking after API more carefully. Constructors are private where they should be private.

Yes, it is still accessible, but using it discouraged rather. I think I will expose it as custom() in next release:

$query = \Couchbase\N1qlQuery::fromString('select * from `default`');
$query->namedParams(['foo' => 'bar']);
//=> object(Couchbase\N1qlQuery)#1 (3) {
//     ["options"]=>
//     array(2) {
//       ["statement"]=>
//       string(23) "select * from `default`"
//       ["$foo"]=>
//       string(3) "bar"
//     }
//     ["adhoc"]=>
//     bool(true)
//     ["crossBucket"]=>
//     bool(false)
//   }

//=> array(2) {
//     ["statement"]=>
//     string(23) "select * from `default`"
//     ["$foo"]=>
//     string(3) "bar"
//   }

I will fix that. Fixed in our repo: http://review.couchbase.org/74845, as well as PR to JetBrains.

It will raise an exception if the document exist already. Documenting exception is the topic of next iteration of API improvements, and it is tracked here PCBC-355

And yeah, I forgot to mention that now I think almost all objects will expose their state for debug needs (e.g. var_dump())

Thank you for feedback

Thanks for the fast answer and the fast fixes! Good to know most of the code inspection problems aren’t “real” as the old code should work as before thanks to aliases. It is just a new feeling to have to rely completely on the documentation. Before, we could have a fast look at the PHP part of the source and saw directly what was implemented. We will get used to it, and having to choose, I take the documentation improvements :wink:

Ok, that means the function really is void now? In 2.2.4 the function returned bool/true. Probably the check of the return value always was superfluous and/or a bad idea, but we must change that then.

I don’t advocate for this constructor being public - in the opposite. But it is a change which can affect API users and is a breaking change in this sense. We will change our code accordingly.

I don’t know another way than just repeating the method definition, documenting it as “alias of foo” and adding a @see annotation. But the method aliases are anyhow something the API users don’t notice at once: couchbase.php only contains the namespaced class names, not the old ones. I tested adding some class_alias() statements, but PhpStorm didn’t find the methods on the alias classes. So I had to refactor to the namespaced version in order to get the power of code analysis for the Couchbase classes. I find the namespaced version better, so we will make that change happily instead of work with two version in code completion etc. But I can imagine others have other opinions about that.

All in all, we probably won’t have to touch our code too much, so we can do without all the aliases. But nice to know the old code will work.

EDIT: Now I found toplevel.php with the class aliases.

I think that the old implementation’s true was pretty much the same as current NULL. They all raise exception in case of error, and do not raise otherwise.

I think it is okay for now. If people used that unspecified constructor previously, I think they can continue to do it with reflection http://php.net/reflectionmethod.setaccessible :slight_smile:

I don’t think that @see will fix the issue, because you still have to browse source method anyway. as you can grep sources and find that old method is aliased to more consistent name, and probably will notice only when I declare alias as deprecated in future.

I also like namespaced version as we do not pollute toplevel as much as previously. Well, we still pollute with aliases, but it is more manageable.

I have just received notification from pecl-dev@ mail list about successful build windows binaries there. The are accessible at http://pecl.php.net/package/couchbase/2.3.0/windows

Functionally they are the same, as ours, hosted here

With only exception that PECL version is not built with igbinary support, and with dynamic linked zlib. Which means that you will see this warning on startup with windows binary from PECL:

[cb,WARN] (pcbc/ext L:393) igbinary serializer is not found

Dynamic zlib linkage there means, that you have to load php_zlib.dll prior php_couchbase.dll, which don’t need if you use ours binary (it statically links zlib and it is always available).

For other systems like Linux or FreeBSD, it does not matter, and everything will be picked up during the build.

Binaries from Remi Collet (remirepo) include igbinary (you still have to load it with extension=igbinary.so if you plan to use it) and zlib support out of the box:

Adding to the above list of issues/“issues”:

  • It seems as though \Couchbase\Bucket::unlock() no longer exists. Is this intentional?
  • Most classes are now final, with most of their methods also being final. I have a thin convenience wrapper around the SDK, and this made it much more difficult to mock things for testing. For example, I would mock \Couchbase\Bucket::get() to ensure that my wrapper properly handled the results. Perhaps this indicates a flaw in my testing methodology, but I’m wondering the value of having everything be final.

Of course it wasn’t intentional, It is very sad that I’ve missed it. The implementation was there, but is not bound to bucket object. I’ve fixed that here http://review.couchbase.org/74875,

We will add this to 2.3.0 release notes, and publish as soon as the release will be ready. Hopefully sooner.

I declared classes and method as final to keep more control over the APIs. I don’t know how you have implemented your wrapper, but you can use aggregation instead of inheritance, and explicitly proxy your methods. In this case all you need is to instantiate your wrapper with test stub instead of real cluster/bucket objects.

If your wrapper might be convenient for other people, it make sense to open ticket with improvement on jira about it, or forum topic to discuss. We are open to improvements and feedback.

FYI, our jenkins CI continuously builds snapshots, so if you need packages for last successful master build, you can find them here:


I can’t install it.
I installed libcouchbase from source "2.7.2.tar.gz"
f0d2d7416a9d3c88af06c9f8f912df5a95bdc73 /usr/local/lib/libcouchbase.so

And pecl install couchbase :
checking for libcouchbase version >= 2.7.2… 0x000000
configure: error: libcouchbase greater or equal to 2.7.2 required

Strange, it should set hex version of libcouchbase during install, php extension detects version like this:

if you see 0x000000, then probably you had issues with installing libcouchbase, could you post the contents of the file /usr/local/include/libcouchbase/configuration.h?

And btw,

MD5 (libcouchbase-2.7.2.tar.gz) = f4e5f527b5e68f8b0a06c4d243786133
#define LCB_VERSION_STRING "2.7.2"
#define LCB_VERSION 0x000000
#define LCB_VERSION_CHANGESET "0xdeadbeef"

But my md5 for 2.7.2 is not the same.

$ wget https://github.com/couchbase/libcouchbase/archive/2.7.2.tar.gz
2017-03-17 10:09:30 (2,21 MB/s) - « 2.7.2.tar.gz » sauvegardé [1111722]
$ md5sum 2.7.2.tar.gz 
2943c15b4ce485b3769987135fe391b0  2.7.2.tar.gz

you should not use github tags for releases, they are generated by github for every tag automatically and not supposed to be used.

The releases available at this page

I will update readme in the extension

Thanks, it’s fine now, but release of github should be usable.
In previous version release of github was usable.

I think we never advertised it, and github does not allow to switch it off. After all github is just a git mirror of official git repository http://review.couchbase.org/libcouchbase :slight_smile:

So a mirror should be usable as the primary source :wink:

it is usable:

$ git clone http://review.couchbase.org/libcouchbase
Cloning into 'libcouchbase'...
remote: Counting objects: 20358, done
remote: Finding sources: 100% (20358/20358)
remote: Total 20358 (delta 14219), reused 19341 (delta 14219)
Receiving objects: 100% (20358/20358), 7.42 MiB | 1.36 MiB/s, done.
Resolving deltas: 100% (14219/14219), done.

From 2.3.1, php extension will detect this case, thank you.

But not for release, so not fully usable.
My package manager was using the release on github.