A newer version of this software is available
You are viewing the documentation for an older version of this software. To find the documentation for the current version, visit the Couchbase documentation home page.
This guide provides information for developers who want to use the Couchbase PHP SDK to build applications that use Couchbase Server.
We will use PHP and access the Couchbase server as part of this exercise; the Couchbase Server can be part of a cluster or it can be stand-alone. This exercise will show you how to:
Download, install and configure the Couchbase PHP SDK
How to use Couchbase and PHP to generate a general page access counter and last-accessed date indicator script
This section assumes that you have the following items set up for your development environment:
PHP 5 and above installed. For more information, see PHP Manual,
Web server installed and configured to serve PHP pages,
Couchbase Server 1.8 or above installed, and available from your development environment. See Couchbase Downloads
This section also assumes you have downloaded and set up a compatible version of Couchbase Server and have at least one instance of Couchbase Server and one data bucket established. If you need to set up these items, you can do with the Couchbase Administrative Console, or Couchbase Command-Line Interface (CLI), or the Couchbase REST API. For information and instructions, see:
Using the Couchbase Web Console, for information on using the Couchbase Administrative Console,
Couchbase CLI, for the command line interface,
Couchbase REST API, for creating and managing Couchbase resources.
The TCP/IP port allocation on Windows by default includes a restricted number of ports available for client communication. For more information on this issue, including information on how to adjust the configuration and increase the available ports, see MSDN: Avoiding TCP/IP Port Exhaustion.
After you have your Couchbase Server set up and you have installed the Couchbase SDK, you can compile and run the following basic program.
Follow these steps to install and set up the PHP SDK:
Download the SDK for your system from the SDK page.
Unpack the archive containing the SDK:
shell> tar xzf php-ext-couchbase-$system-$arch.tar.gz
The resulting directory includes a file couchbase.so which is the PHP extension for the SDK. Note the path to this file.
Find the php.ini
file for your PHP interpreter. Try:
shell> phpi -i | grep ini
The output provided will have configuration file that is loaded for PHP, for instance:
Loaded Configuration File => /private/etc/php.ini
Open the php.ini file and add the path to your couchbase.so file. For example:
extension=/path/to/couchbase.so
To verify you have set up the PHP SDK correctly follow these steps:
Create a new file named test.php andplace the following test code it:
<?php
$cb = new Couchbase("127.0.0.1:8091", "username", "password", "default");
$cb->set("a", 1);
var_dump($cb->get("a"));
?>
Save the new script as test.php.
Start your Couchbase Server. Note the ip address and port for Couchbase Server and any username and password.
If needed, update the IP address, username and password in test.php with your Couchbase Server information.
Run your test script:
shell> php test.php
Couchbase Server returns 1.
To demonstrate how to use Couchbase PHP SDK with Couchbase Server we will built a web page counter. The counter will record the last access date for a web page. we’ll implement those features in PHP using the Couchbase library.
To store data in Couchbase Server, you provide information in a way that is similar to a PHP Array. You can store a value with a key, then retrieve the value by the key. In this exercise, we will store and retrieve integer and string data.
In the first part of our PHP script, we create a connection with Couchbase Server:
<?php
#Create the Couchbase object
$cb_obj = new Couchbase("127.0.0.1:8091", "user", "pass", "default");
In the next section of our script, we find out the name of the script currently running on the web server. Typically the name would be for the counter PHP script itself:
#determine the name of the script currently running
$script_name=$_SERVER["SCRIPT_NAME"];
In this case we set the $script_name
variable to be the script name that is
stored in a PHP environment variable, SCRIPT_NAME
. Then we try to retrieve an
existing record for the key $script_name
from Couchbase Server. This will tell
us if the key already exists or not and wheter we need to create a new record
with the key:
#if the script name doesn't exist as a Couchbase key then add
$script_access_count=$cb_obj->get($script_name);
if($cb_obj->getResultCode() == COUCHBASE_KEY_ENOENT){
#the add will fail if it has already been added
$cb_obj->add($script_name,0);
}
Then we use one of the Couchbase SDKs increment methods to add one to the page
access count. We provide the key, which is the $script_name
, to increase the
counter by one. We also output the access count in a string:
#increment the integer associated with the script name
$access_count = $cb_obj->increment($script_name);
#print the current access count
echo "this page ($script_name) accessed $access_count times<br>";
In this final part of our access counter script, we retrieve the last date and time that the script had been accessed. Again, we use the key as a parameter to get the value from Couchbase Server:
#retrieve the last access date/time of the script.
#the key name is the script name prefixed with DATE::
$last_access_date=$cb_obj->get("DATE::" . $script_name);
#handle the case where this is the first access to the script
#and that key doesn't yet exist
if($last_access_date == NULL){
$last_access_date = "never";
}
echo "this page last accessed: " . $last_access_date;
#save the current access date/time in a script
$cb_obj->set("DATE::" . $script_name,date("F j, Y, g:i:s a "));
?>
You can save this sample can be saved into a PHP file in a directory on your web server, such as test.php
When you load test.php page you’ll see something like this on the first load:
this page (/test.php) accessed 1 times
this page last accessed: never
And like this on subsequent loads, with the access count incrementing and the date/time increasing:
this page (/test.php) accessed 2 times
this page last accessed: June 1, 2011, 10:06:04 am
Reload the script a few times in rapid succession and you’ll see a spike in traffic in the Couchbase Web UI. So, what exactly is our script doing to achieve this?
The first line of the script creates a Couchbase object ( $cb_obj
). The
parameters define a Couchbase server hostname and port as well as user
credentials and the default bucket name to the server pool that we’ll be
accessing.
If you are running Couchbase on a single node, you specify its hostname and port. If you are running a multi-node cluster, you only need to point to a single node in a cluster as the PHP extension will transparently determine any cluster topology and route requests to the right servers as well as react on topolgy changes.
$cb_obj = new Couchbase("localhost", "user", "pass", "default");
We then get the "SCRIPT_NAME"
value from the $_SERVER
Array, which tells us
in which script this PHP code is currently running.
$script_name=$_SERVER["SCRIPT_NAME"];
Now we connect to Couchbase to retrieve the integer access count associated with this script using the script name (determined above) as the key.
$script_access_count=$cb_obj->get($script_name);
If there is no such key in Couchbase (because the page has not previously been
accessed), the request returns a NULL
value, and the result code of the call
to the get method is the Couchbase constant COUCHBASE_KEY_ENOENT
(resource not
found). In this case we use the add
method to set the value to zero. If,
between the failed get
and add
method calls, the key has already been added
by another process, the add
will fail and we will not overwrite the added
value. This sort of attention to concurrency issues is overkill for the current
application, as a missed counting of a single script access is unlikely to be
critical; however, it illustrates how to write Couchbase code to avoid
unintentionally overwriting keys:
if($cb_obj->getResultCode() == COUCHBASE_KEY_ENOENT){
$cb_obj->add($script_name,0);
}
The key associated with the script name count is then incremented by one for the current script access, and that incremented value is returned and printed out. The increment method is atomic, consisting of both an increment and retrieval of the resultant value. If the Couchbase server receives two such requests, they will be queued for action in the order they were received and return the correct count to each requesting process.
$access_count = $cb_obj->increment($script_name);
echo "this page ($script_name) accessed $access_count times<br>";
To retrieve and update the last access date of the script we’re doing something similar to what we did for the script access count, however, instead of adding and incrementing an integer, we’re adding and updating a string.
As a key for the date any given script was accessed, we’ve prepended the string
"DATE::"
to the beginning of the script name; thus the key for the last access
date of our test.php script is "DATE::test.php"
. We first try to get the date
of last access and assign it to the $last_access_date
variable. If this fails
(the get
method returns a Boolean NULL
value and the subsequent
getResultCode
call returns COUCHBASE_KEY_ENOENT
) that means it hasn’t yet
been set, so the script has not previously been accessed. In that case we’ll set
$last_access_date
to “never”. We then print out the value of
$last_access_date
.
$last_access_date=$cb_obj->get("DATE::" . $script_name);
if($cb_obj->getResultCode() == COUCHBASE_KEY_ENOENT){
$last_access_date = "never";
}
echo "this page last accessed: " . $last_access_date;
We now set the access date for this access of the script for retrieval on the next access.
$cb_obj->set("DATE::" . $script_name,date("F j, Y, g:i:s a "));
And that’s the end of the script. There is no method in the Couchbase library to close the connection to the server, however it will automatically be closed at the end of script execution.
This has been a brief outline of some basic features of the Couchbase API in
PHP. We’ve used the add
, get
, set
, increment
and getResultCode
methods
of the Couchbase class to store and retrieve integers and strings. There are a
number of other methods that allow for scalable development in a multiprocess
and multi-server environment.
This tutorial will guide you through development of an application using PHP and Couchbase.
SQL databases and key-value stores such as Couchbase are general solutions to the web development problem of maintaining applications state across multiple systems and over time; as such they are similar, but there are many important differences. Most PHP developers are familiar with SQL databases, so the emphasis on the Couchbase implementation will be on how it differs from using SQL.
This section assumes that you have installed Couchbase PHP SDK, that your web server is properly configured to serve PHP pages and that you’ve installed the Couchbase server on your development machine. We assume you have at least one instance of Couchbase Server and one data bucket established. If you need to set up these items in Couchbase Server, you can do with the Couchbase Administrative Console, or Couchbase Command-Line Interface (CLI), or the Couchbase REST API. For information and instructions, see:
Using the Couchbase Web Console, for information on using the Couchbase Administrative Console,
Couchbase CLI, for the command line interface,
Couchbase REST API, for creating and managing Couchbase resources.
After you have your Couchbase Server set up and you have installed the Couchbase SDK, you can compile and run the following basic program.
The demonstration application provides a means of chatting over the web: WebChat. It’s a rudimentary implementation with various features specifically designed to demonstrate the PHP/Couchbase interface. It allows user registration, login, logout as well as adding chat messages, viewing them and deleting them. To do this it uses add, increment, delete and append Couchbase key manipulation methods.
One of the first things usually undertaken in an SQL-based web application development project is the creation of a schema: the structure of database tables and their relationship. Couchbase has no tables. Like a PHP Array data type, all we have are key-value pairs to work with. On top of that, there is no mechanism for enumerating the keys you’ve created, so unless you know the keys to ask for you won’t be able to find any of your data.
Our WebChat workflow will be simple. If you try to access the system and aren’t logged in it will route you to a login page (login.php). If you’re not registered, you can go to the registration page (register.php), and from there log in. Once you’re logged in, you are routed to the chat page (chat.php) and can engage in chat with other logged-in users: you can add a comment or delete your own comments. From there you can log out (logout.php). This workflow is summarized in Figure 1.
Let’s think a little bit about how we’re going to store our user information. As
mentioned previously, there are no SQL style schemas in Couchbase, only keys and
values. In addition, we can’t enumerate a list of keys in the Couchbase bucket
we’re using. This means we have to know what we’re looking for before we look;
we can’t select * from TABLE
as we would using an SQL query. Also, even
assuming we’ve only got one application using the given bucket, care must be
taken in key naming conventions so that collisions don’t occur with keys of
different types.
For our keys, we’ll prefix each key first with the application name, then the key type, for example a user named jsmith will get a user key in Couchbase of chat::user::jsmith, where the value associated with that key will contain the account information. We’re prefacing the user key with the application name in case we later choose to share this bucket with another application; if all applications follow this convention we’re creating a namespace for each application and we can be avoid key collisions between apps.
For the user comments we’ll keep a single key that lists the maximum comment number so far achieved, and the comments themselves will have keys containing their comment number, for example, chat::COMMENT#23
This is another method of determining the keys for values we may want to retrieve, somewhat different from that of the user list discussed above.
Though we won’t be implementing an administration function for managing users in
this example application, we want to design our data model to support that
possibility. This means that it should be possible to enumerate all users. To
allow this, for each user we add, we’ll append the username to a string held in
the key chat::userlist
. We’ll be using the API append()
method to that this.
append()
is functionally equivalent to doing a get()
on the key, appending
the new user to the returned text, and storing it again. The append()
method
requires less code and is also atomic, while a get, modify, and update sequence
would not be.
The value held by a given key is of a default maximum size of 1 megabyte, though it can be increased with server side configuration. This should be kept in mind if you are, for example, doing many appends in long running or large-scale applications that are likely to exceed this limit.
WebChat follows a standard structure for small and medium sized PHP projects, which is shown in the list below. The base directory contains PHP scripts corresponding to application views that the user will see (login.php, logout.php, register.php, chat.php), while a subdirectory (here named include) contains utility classes for page layout (header.php, footer.php) and a library file (include.php) of classes that do most of the work of the application. Finally the css directory contains our application specific style sheet (chat.css) which makes the generated web pages pretty and helps to avoid cluttering our PHP files with excessive HTML formatting.
index.php
login.php
logout.php
register.php
chat.php
css
include
include.php
header.php
footer.php
We’ll discuss each of these files in turn to explain how the application works, with the exception of chat.css, which makes the output prettier, but doesn’t affect the way it works. All the files are available in the provided supplemental file Zip file.
The first file, index.php (Listing 1), provides a redirect. If a user attempts to access the root directory, we’ll redirect to chat.php that will, in turn, redirect the page to login.php if they’re not already logged in.
Listing 1: index.php
<?php
header("Location: chat.php");
exit;
?>
Listing 2 shows the header file which sets the stylesheet, the page title and sets up the HTML markup.
Listing 2: header.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title><?php
echo ($title);
?></title>
<link rel="stylesheet" href="css/chat.css" type="text/css"
media="screen" /> </head>
<body>
<div id="frame">
<div id="header">
<h1><?php
echo ($APP_NAME);
?></h1>
</div>
Listing 3 shows footer.php, which displays login status and closes off the markup.
Listing 3: footer.php
<div id="footer">
<?php
if(empty($_SESSION{"userid"})){
echo("Not logged in.<br>");
?>
<a href="login.php">Login here</a>
<?php
}else{
echo("Logged in as user <i>" . $_SESSION{"userid"} . "</i>");
echo("<br>");
echo("<a href='logout.php'>Logout</a>");
}?>
</div>
</div>
</body>
</html>
Like pieces of bread around a sandwich, the header and footer are boring but mandatory items included at the top and bottom of every page output by our application. Like sandwiches, all the interesting stuff happens between the bread.
include.php contains the meat of our application, and you’ll see it included
first at the top of every PHP page, even before the header.php file. It starts
the PHP session and contains a variety of constants used elsewhere in the
application and the User
, Comment
and CouchbaseSingleton
classes that do
the bulk of the work in this application.
The first two clauses of include.php (Listing 4) set the error output and warnings to maximum and direct their output to the web server. While this is something we would turn off on a production web server, its helpful to see all warnings and errors while in development. The global constants are accessible by other pages and classes called after this file has been included.
Listing 4: include.php constants and settings
error_reporting(E_ALL);
ini_set("display_errors", 1);
//start our session
session_start();
//Global constants
$APP_NAME="PHP Couchbase WebChat";
define('APP_PREFIX',"chat");
define('KEY_DELIM',"::");
define('COUCHBASE_SERVER',"localhost:8091");
define('COUCHBASE_USER','Administrator');
define('COUCHBASE_PASS','asdasd');
define('COUCHBASE_BUCKET','default');
The $APP_NAME
variable is output by the header at the top of every page.
The constants that are set using the define
function are used by the classes
defined later in the file. APP_PREFIX (chat)
is added to the front of every
key avoid potential key name collisions with other applications using the same
bucket. KEY_DELIM
(set to two colons “::”)is used to delimit the various
portions of the keys; so, for example, the key for comment number 99 will be the
concatenation of APP_PREFIX, KEY_DELIM
, the key type (in this case comment),
the KEY_DELIM
again and the comment number: chat::comment::99
.
COUCHBASE_SERVER
, COUCHBASE_USER
, COUCHBASE_PASS
and COUCHBASE_BUCKET
indicate the location of the Couchbase server and bucket we’ll be connecting to.
You can change these to match the address and port of your own server.
The next part of the include.php file contains the three classes that do most of
the work: CouchbaseSingleton
, User
and Comment
.
The CouchbaseSingleton
class (Listing 5) is a wrapper for the Couchbase
library class. Both the User
and Comment
class (which we’ll see next)
require a Couchbase library connection to the Couchbase server.
Listing 5: include.php CouchbaseSingleton
class
/**
* Singleton Couchbase class
* This keeps a single global copy of the Couchbase
* Couchbase connection.
*/
class CouchbaseSingleton{
private static $instance;
private static $cb_obj;
/**
* Construct the object
*/
private function __construct() {
}
/**
* Initialize this class after construction
*/
private function initialize(){
self::$cb_obj = new Couchbase(COUCHBASE_SERVER, COUCHBASE_USER, COUCHBASE_PASS, COUCHBASE_BUCKET);
self::$cb_obj->setOption(COUCHBASE_OPT_COMPRESSER,false);
}
/**
* Return the singleton instance, constructing and
* and initializing it if it doesn't already exist
*/
public static function getInstance() {
if(!self::$instance) {
self::$instance = new self();
self::$instance->initialize();
}
return self::$instance;
}
/**
* Return the Couchbase object held by the singleton
*/
public static function getCouchbase(){
return(self::$cb_obj);
}
}
Rather than have more than one Couchbase
library instance created, we use
CouchbaseSingleton
to ensure we initialize and use only one copy per
invocation of the application. When the static method getInstance()
is called,
it creates a CouchbaseSingleton
instance and initializes a Couchbase
instance, which may be retrieved using the getCouchbase()
method. If a
Couchbase connection is required, the call:
CouchbaseSingleton::getInstance()->getCouchbase()
will provide a reference
with the appropriately initialized Couchbase server information and avoid
recreating one. Though this is overkill for the current implementation, if it
were to get significantly more complex (as applications tend to), it avoids the
issue of multiple Couchbase library instances being instantiated by different
classes.
The Couchbase library has limited functionality for connecting to servers; it does not directly support vBuckets or SASL authentication. You can, however, configure multiple servers with associated weights (connection priorities) by specifying hostname, port and weight. One solution is to use client-side Moxi to act as a proxy service to the Couchbase Server cluster.
The key method of the CouchbaseSingleton
class is initialize()
, which
configures the connection to the Couchbase server. In initialize()we turn off
compression using: setOption(COUCHBASE_OPT_COMPRESSER,false)
as the Couchbase
append
method is only supported if the Couchbase records are not compressed.
The User class (Listing 6) handles user related actions; registration, login and logout.
Listing 6: include.php User
class
/**
* User class
* This handles user interactions with Couchbase through
* the Couchbase interface.
*/
class User {
private $last_error_string;
/**
* Create a user account based on provided userid
* and password.
* @param string $userid
* @param string $password
* @return boolean
*/
public function createUserAccount($userid, $password) {
$error = "";
if(!preg_match("/^\w{4,10}$/", $userid)) {
$error .= "Illegal userid '<i>$userid</i>'<br>";
}
if(!preg_match("/^.{4,10}/", $password)) {
$error .= "Password must have between 4 and 10 characters";
}
if($error != "") {
$this -> last_error_string = $error;
return false;
}
$cb_obj = CouchbaseSingleton::getInstance() -> getCouchbase();
//check to see if the userid already exists
$userid_key = APP_PREFIX . KEY_DELIM . "user" .
KEY_DELIM . $userid;
$passwordHash = sha1($password);
if($cb_obj -> add($userid_key, $passwordHash)) {
//now that we've added the userid key we'll add it to the userlist
$userlist_key = APP_PREFIX . KEY_DELIM . "userlist";
if(!$cb_obj -> add($userlist_key, $userid)) {
$cb_obj -> append($userlist_key, KEY_DELIM . $userid);
}
return true;
} else {
$result_code = $cb_obj -> getResultCode();
if($result_code == COUCHBASE_KEY_EEXISTS) {
$this -> last_error_string .=
"User id '<i>$userid</i>' exists, please choose another.";
} else {
$this -> last_error_string .=
"Error, please contact administrator:" .
$cb_obj -> getResultMessage();
}
return false;
}
}
/**
* Attempt to login the user
* @param string $userid
* @param string $password
* @return boolean
*/
public function loginUser($userid, $password) {
$cb_obj = CouchbaseSingleton::getInstance() -> getCouchbase();
//check to sees if userid exists with the same password hashed
$userid_key = APP_PREFIX . KEY_DELIM .
"user" . KEY_DELIM . $userid;
$submitted_passwordHash = sha1($password);
$db_passwordHash = $cb_obj -> get($userid_key);
if($db_passwordHash == false) {
return (false);
}
//do we match the password?
if($db_passwordHash == $submitted_passwordHash) {
$_SESSION{"userid"} = $userid;
return true;
} else {
return false;
}
}
/**
* Log the user out
*/
public function logoutUser() {
session_unset();
session_destroy();
}
/**
* Get the error string from the last action
* @return string
*/
public function getLastErrorString() {
return $this -> last_error_string;
}
}
The createUser
method is called from the register.php file, which we’ll see
later. It checks that the userid and password are of the correct format (userid
4-10 alphanumeric or underscore characters, password 4-10 characters), then
attempts to add the new user to the database. The key is of the format:
Chat::user::$userid
, and the value is the sha1 hash of the password. If it
fails (the method returns false), we set a private class error variable
$last_error_string
, which can be retrieved using the getLastErrorString
method. There are many possible failure modes for an add (see the Couchbase
documentation; in this case we’re only dealing with one explicitly, where the
user id is already taken. In that case the error code is
COUCHBASE_KEY_EEXISTS
. All other error cases are converted to text using the
getResultMessage()
method for text display to the user.
If the user id addition is successful then we add it to the user list (stored in
the chat::userlist
key) with the append
method. This will result in a value
for the userlist of the form bjones::fdavis::jsmith
enumerating all user ids
that have successfully created accounts. Though we don’t currently use this
elsewhere in the application, if we were to create a user management
administration view, we’d need some way to find the full list of user ids. This
list is where we would get that information.
The loginUser
method of the User class is called from the login.php page. It
retrieves the user id record (if it exists) from Couchbase, and then compares
the retrieved sha1 hash with the hash of the provided password. If they match,
the user is logged in by setting the userid value in the session variable.
The logout
method is particularly simple; it destroys the PHP session for the
current user.
The Comments
class (Listing 7) manages adding, listing and deleting comments.
Listing 7: include.php Comment
/** * Comments class for managing comments in Couchbase
* through the Couchbase library
*/
class Comments {
/**
* Return the last n comments
* @param integer $count
* @return Array
*/
public function getLastComments($count) {
$cb_obj = CouchbaseSingleton::getInstance() -> getCouchbase();
$comment_count_key = APP_PREFIX . KEY_DELIM . "chatcount";
$script_comment_count = $cb_obj -> get($comment_count_key);
$comment_key_list = array();
for($i = $script_comment_count; $i > 0 &&
$i > ($script_comment_count - $count); $i--) {
array_push($comment_key_list, "COMMENT#" . $i);
}
$null = null;
return ($cb_obj -> getMulti($comment_key_list,
$null, Couchbase::GET_PRESERVE_ORDER));
}
/**
* Add a comment to the comment list
* @param string
*/
public function addComment($comment) {
$cb_obj = CouchbaseSingleton::getInstance() -> getCouchbase();
if($comment != "") {
$comment_count_key = APP_PREFIX . KEY_DELIM . "chatcount";
$comment_count = $cb_obj -> get($comment_count_key);
if($cb_obj -> getResultCode() == COUCHBASE_KEY_ENOENT) {
$cb_obj -> add($comment_count_key, 0);
}
$script_comment_count = $cb_obj -> increment($comment_count_key);
$cb_obj -> add("COMMENT#" . $script_comment_count, $_SESSION{"userid"} .
KEY_DELIM . $_POST["comment"]);
}
}
/**
* delete a comment from the list by number
* @param integer $number
*/
public function deleteComment($number) {
$cb_obj = CouchbaseSingleton::getInstance() -> getCouchbase();
$comment_key = "COMMENT#" . $number;
$result = $cb_obj -> get($comment_key);
$elements = explode(KEY_DELIM, $result);
$userid = array_shift($elements);
//make sure user who created is deleting
if($userid == $_SESSION{"userid"}) {
$result = $cb_obj -> delete($comment_key);
}
}
}
?>
The addComment
method takes the provided comment and adds it to the Couchbase
database. The current comment number is stored in the $comment_count_key
key
(chat::chatcount)
. To add the comment to the database, the comment count key
is incremented and we take the resultant number as our next comment number.
Couchbase guarantees that the increment and retrieval are atomic, so we can be
sure that we won’t collide with comment key number generated by another instance
of the web application. The key for the comment is created, of the form
chat::COMMENT#9
. The corresponding comment value is of the form
userid::comment, so that the comment is prepended by the identity of the
submitter. We could serialize a data structure into the value if desired;
however we’ve chosen to use text here for the sake of simplicity and clarity.
The deleteComment
method takes a comment number as an argument and deletes
that comment if the same user who submitted the comment requested the action.
The getLastComments
method returns the specified number of comments in an
array, counting backwards from the most current comment. The current comment
count is retrieved to determine the most recent comment number. From this, an
Array of keys is generated counting backwards from that comment, and the
Couchbase getMulti method is used to retrieve them all simultaneously, which is
more efficient than looping and retrieving each individually. The results are
returned in an Array with the key being the request key and the value being the
value retrieved from Couchbase. If a key doesn’t exist because that comment has
been deleted, the value returned is empty.
The next few listings describe pages that provide views of the application; login, logout, register and chat.
The login view (Figure 2) is a userid and password form.
The login code (login.php, Listing 8) passes the userid and password fields to the createUser method of the User class we saw previously in include/include.inc.
Listing 8: login.php8
<?php
include_once ("include/include.php");
$loginfailed = "";
if(!empty($_POST{"userid"})) {
$user = new User();
if(!$user -> loginUser($_POST{"userid"}, $_POST{"password"})) {
$loginfailed = "Login attempt failed";
}
}
if(!empty($_SESSION{"userid"})) {
header("Location: chat.php");
exit ;
}
$title = "Login";
include_once ("include/header.php");
?>
<div id="content">
<h2>Login to MemChat</h2>
<?php echo $loginfailed
?><br>
<form method="post" action="login.php" id="loginform" style="width:40%">
<fieldset>
<label for="userid">
User id:
</label>
<input type="text" name="userid" length=20>
<label for="password">
Password:
</label>
<input type="password" name="password" id="password" length=20>
<input type="submit" name="login" id="registration">
</fieldset>
</form>
Register
<a href="register.php">here</a> if you don't have an account.
</div>
<?php
include_once ("include/footer.php");
?>
If the user is already logged in (i.e., there is a value for
$_SESSION{"userid"}
), they are immediately redirected to the chat.php file.
If there is an error on login (in which case the loginUser
method returns
false) the login page is shown again with a login error.
The logout screen (Figure 3) just indicates the logged out status of the user.
The logout code (logout.php, Listing 9) calls the User
class logoutUse
r
method, which we’ve seen already, then clears the current user PHP session.
Listing 9: logout.php
<?php
include_once("include/include.php");
$userid=$_SESSION{"userid"};
$title="Logout";
include_once("include/header.php");
$user = new User();
$user->logoutUser();
echo("$userid logged out");
include_once("include/footer.php");
?>
The register screen (Figure 4), is similar to the login page and provides a userid and password form.
The register code (register.php, Listing 10) is similar to login; it takes a userid and password and calls the User class createUserAccount method; if an error is returned (for example the userid already exists) then the error is displayed.
Listing 10: register.php
<?php
include_once("include/include.php");
$title="Register User";
include_once("include/header.php");
$result = false;
//opening the register page logs you out
$user=new User();
$user->logoutUser();
if(!empty($_POST{"userid"})){
$userid=$_POST{"userid"};
$result = $user->createUserAccount($_POST{"userid"},$_POST{"password"});
if($result == true){
echo "<div id='error'>" .
"User id '<i>$userid</i>' successfully created.
<br> " .
"<a href='login.php'>Login here</a>" .
"</div>";
}else{
echo "<div id='error'>" . $user->getLastErrorString() .
"</div>";
}
}
if($result != true){
?>
<div id="content">
<h2>Register to use WebChat</h2>
<form method="post" action="register.php" id="registrationform"
style="width:40%">
<fieldset>
<label for="userid">
User id:
</label>
<input type="text" name="userid" id="userid">
<label for="password">
Password:
</label>
<input type="password" name="password" id="password">
<input type="submit" name="registration" id="registration">
</fieldset>
</form>
<small>
<i>
User id must have between 4 and 10 characters.
<br>
Only letters, numbers and underscore characters are permitted
</i>
</small>
</div>
<?php
}
include_once("include/footer.php");
?>
The chat view (Figure 5) displays the user chat form (a text field and a button), and the last ten submitted comments. The delete buttons in the “Action” allow a user to delete their own comments.
The chat view (chat.php, Listing 11) has the most user interaction and behavioral complexity, however the bulk of this behavior is implemented in the Comments class; the chat.php code is relatively simple.
Listing 11. chat.php
<?php
include_once ("include/include.php");
if(empty($_SESSION{"userid"})) {
header("Location: login.php");
}
$title = "Chat";
include_once ("include/header.php");
?>
<form method="post" action="chat.php" id="chat">
<div>
<input type="text" name="comment" id="comment" maxlength="50" size="50"/>
<input type="submit" name="submitcomment" id="submitcomment" value="Submit
comment" />
</div>
</form>
<br>
<?php
$comments = new Comments();
if(!empty($_POST{"comment"})) {
$comments -> addComment($_POST{"comment"});
}
if(!empty($_POST{"delete"})) {
$comments -> deleteComment($_POST{"commentnum"});
}
$comment_list = $comments -> getLastComments(10);
$keys = array_keys($comment_list);
?>
<table>
<tr>
<th width="10%" align="center">Comment #</th>
<th>Action</th>
<th>User ID</th>
<th width="60%">Comment</th>
</tr>
<?php
foreach($keys as $key) {
echo "<tr>\n";
$result = explode(KEY_DELIM, $comment_list{$key});
$userid = array_shift($result);
$message = implode(KEY_DELIM, $result);
$commentnum = array_pop(explode("#", $key));
$actionlink = "";
if(empty($userid)) {
$userid = "?";
$message = "<i>deleted</i>";
}
if($_SESSION{"userid"} == $userid) {
$actionlink =
"<form method='post' action='chat.php' id='message" . $commentnum . "'>";
$actionlink .= "<input type='hidden' value='$commentnum'
name='commentnum'>";
$actionlink .= '<input type="submit" value="delete" name="delete"
style="background: none; border: none; font-style: italic;" >';
$actionlink .= "</form>";
}
echo("<td>$commentnum</td><td>$actionlink</td><td>
$userid</td><td>$message</td>\n");
echo "</tr>\n";
}
?>
</table>
<?php
include_once ("include/footer.php");
?>
If a non-logged in user accesses the chat view, they are immediately routed to
the login page. If they are logged in, a chat form is displayed with the last 10
comments shown in decreasing order (i.e. increasing in age as they go down the
page). If the currently logged in user created a given comment, a button to
delete it is shown in the action column (Figure 5) for that comment. The delete
button looks like a link, but it is actually a borderless button on a form that
does a POST submission to the chat.php page. Comment
class methods handle both
comment submission and comment deletion.
WebChat is an example application that outlines various features of Couchbase as they apply to PHP development. We’ve demonstrated how to add, delete, append and retrieve data from Couchbase using the Couchbase library in addition to identifying error states. This example should give you a clear idea of how to begin using Couchbase with your own PHP application.
This chapter explains how to move existing codebases to the Couchbase PHP API.
ext/memcached is a popular PHP extension for memcached. You can use Couchbase Server in places where you use memcached today and take advantage of Couchbase Server’s unique features like scaling over multiple physical machines, persistence or view querying (2.0 or later) as well as many others.
This section will explain how to migrate an existing codebase from ext/memcached to ext/couchbase.
ext/couchbase is our new PHP extension around libcouchbase, our also new C-library for connecting to Couchbase Server. ext/couchbase is mostly API compatible with ext/memcached. However, we made a few changes to take advantage of libcouchbase’s unique features.
You can use ext/memcached with Couchbase Server just fine (using the binary protocol), so why would you want to migrate to ext/couchbase?
Easy! ext/memcached is what we call a “dumb-client” while ext/couchbase is a “smart client”. This isn’t meant to sound any derogatory, of course, but points to the fact that with memcached you always have a single server to connect to or you are manually managing multiple ones. Couchbase server can manage multiple servers for you, so you still only connect to one physical node, but ext/couchbase is “smart” enough to figure out which server to talk to for a given operation.
And like we said earlier, you get first class access to all the other features Couchbase has over memcached. We hope that is all reason enough to migrate. Now let’s go.
Let’s start with a list of the differences.
This list shows the differences between the ext/memcached and the ext/couchbase APIs.
The constructor for ext/couchbase takes a string identifying one of the cluster nodes. From there ext/couchbase figures out all the other nodes in a cluster automatically, whereas in ext/memcached you’d have to use multiple calls to the addServer() method, that doesn’t exist in ext/couchbase.
ext/memcached’s $persistent_id parameter allows you to tie specific instances of Memcached to persistent connections. In ext/couchbase connections are persistent by default and you can turn them off with the second optional parameter to __construct() and setting it to false
Note that calling new Couchbase($url) will make a REST call to Couchbase Server to determine the cluster topology. This is a relatively expensive call and that’s the reason why we use persistent connections by default, so that this call doesn’t have to be made more often then necessary, and most importantly not on every user-request.
That means, if you have any code that calls new Memcached(); in a tight loop, you want to move the call to new Couchbase(); to outside of that loop. If you compare performance between ext/memcached and ext/couchbase and find ext/couchbase to run at ½ the speed of ext/memcached, look for places where new Couchbase(); is called in a loop or otherwise repeatedly.
With ext/couchbase you no langer have to manually manage multiple memcached instances. All methods that are related to that use case aren’t supported by ext/couchbase.
append()’s signature in ext/couchbase is almost identical append() to ext/memcached. The only difference is two optional arguments: int $expiration and float $cas_token. $expliration lets you updated the expiration time for a key and $cas_token allows you to make the append operation fail if they key’s existing cas_token has changed.
append() keeps working like you expect it, but you get the new case functionality if you like to use that.
prepend()’s signature in ext/couchbase is almost identical prepend() to ext/memcached. The only difference is two optional arguments: int $expiration and float $cas_token. $expliration lets you updated the expiration time for a key and $cas_token allows you to make the prepend operation fail if they key’s existing cas_token has changed.
prepend() keeps working like you expect it, but you get the new case functionality if you like to use that.
decrement() adds three more optional parameters.
bool create = false determines whether ext/couchbase should create the key if it doesn’t exist. With this you can model cases where you want to avoid decrementing non-existent keys. The default is false, do not create non existent keys.
int $expiration = 0 lets you set a new expiration time for the key. The default is 0, do not expire.
int initial = 0 allows you to specify an initial value in case you set create = true. This allows you to start at an arbitrary value without the need for running extra operations.
decrement() will work like it does in ext/memcached, but you will be able to use more features with the optional arguments.
increment() adds three more optional parameters.
bool create = false determines whether ext/couchbase should create the key if it doesn’t exist. With this you can model cases where you want to avoid incrementing non-existent keys. The default is false, do not create non existent keys.
int $expiration = 0 lets you set a new expiration time for the key. The default is 0, do not expire.
int initial = 0 allows you to specify an initial value in case you set create = true. This allows you to start at an arbitrary value without the need for running extra operations.
increment() will work like it does in ext/memcached, but you will be able to use more features with the optional arguments.
delete() changes the second optional argument from int $time to float $cas_token. Delete with a timeout isn’t supported by Couchbase, we hence don’t allow a timeout to be specified with a delete().
Instead delete() gains the opportunity to use a cas value, so you can avoid deleting a key with a changed cas value.
If you rely on delete() with a time, you need to rework that part of your application.
Like delete(), flush() doesn’t support flushing after a timeout.
If you rely on flush() with a time, you need to rework that part of your application.
Both ext/memcached and ext/couchbase use a number of constants throughout the API. Most notably result codes and configuration options.
For many constants, you can just switch the Memcached:: (or MEMCACHED_) prefix to the Couchbase:: (or COUCHBASE_) prefix. The constants below are the exception to this rule.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles distribution of keys over a cluster automatically. For that reasons specifying a hash algorithm doesn’t make much sense. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles low-level network settings transparently. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles low-level network settings transparently. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles low-level network settings transparently. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles low-level network settings transparently. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles low-level network settings transparently. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles low-level network settings transparently. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles low-level network settings transparently. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles low-level network settings transparently. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles low-level network settings transparently. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles low-level network settings transparently. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles low-level network settings transparently. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles low-level network settings transparently. There is no equivalent for this constant in ext/couchbase.
ext/couchbase handles low-level network settings transparently. There is no equivalent for this constant in ext/couchbase.
There is no equivalent for this constant in ext/couchbase.
There is no equivalent for this constant in ext/couchbase. JSON support is always included.
There is no equivalent for this constant in ext/couchbase.
The ext/couchbase equivalent of this constant are Couchbase::SUCCESS and COUCHBASE_SUCCESS respectively.
The ext/couchbase equivalent of this constant are Couchbase::ERROR and COUCHBASE_ERROR respectively.
The ext/couchbase equivalent of this constant are Couchbase::UNKNOWN_HOST and COUCHBASE_UNKNOWN_HOST respectively.
The ext/couchbase equivalent of this constant are Couchbase::PROTOCOL_ERROR and COUCHBASE_PROTOCOL_ERROR respectively.
There is no equivalent of this constant in ext/couchbase.
There is no equivalent of this constant in ext/couchbase.
The ext/couchbase equivalent of this constant are Couchbase::NETWORK_ERROR and COUCHBASE_NETWORK_ERROR respectively.
The ext/couchbase equivalent of this constant are Couchbase::KEY_EEXISTS and COUCHBASE_KEY_EEXISTS respectively.
The ext/couchbase equivalent of this constant are Couchbase::NOT_STORED and COUCHBASE_NOT_STORED respectively.
The ext/couchbase equivalent of this constant are Couchbase::KEY_ENOENT and COUCHBASE_KEY_ENOENT respectively.
The ext/couchbase equivalent of this constant are Couchbase::PROTOCOL_ERROR and COUCHBASE_PROTOCOL_ERROR respectively.
There is no equivalent of this constant in ext/couchbase.
There is no equivalent of this constant in ext/couchbase.
There is no equivalent of this constant in ext/couchbase.
There is no equivalent of this constant in ext/couchbase.
The ext/couchbase equivalent of this constant are Couchbase::NETWORK_ERROR and COUCHBASE_NETWORK_ERROR respectively.
The ext/couchbase equivalent of this constant are Couchbase::PROTOCOL_ERROR and COUCHBASE_PROTOCOL_ERROR respectively.
An example below on creating a single connection to the default bucket at Couchbase Server:
$cb = new Couchbase("192.168.1.200:8091", "user", "pass");
The Couchbase PHP SDK can also create a persistent connection which can be used for multiple request and response from processes. When you use a persistent connection, the first connection request from an SDK will take longer than subsequent SDK requests. Each subsequent request from a client application automatically reuses the existing instance of the client and the connections for that client. The following example demonstrates how you create a persistent connection:
$cb = new Couchbase("192.168.1.200:8091", "user", "pass", true);
The parameters you use include host:port, username, password, bucket name, and a boolean. The boolean set to true indicates that you want to create a persistent connection. By default connections are not persistent.
When you use a persistent connection, the first request from a client application will typically require more CPU and time to create a connection, compared to operations that rely on an existing connection. Subsequent requests from a client application will automatically reuse this existing persistent connection based upon the name of the connection.
Be aware many web servers such as Apache will automatically take control of the connection instance and may destroy but also rebuild a connection after a certain number of requests. This is part of the web server functioning, and enables the web server to create a pool of reuseable connections.
To plan for redundancy in the event of a failure of the Couchbase Server node you specify to the client library, you may wish to supply multiple hosts. For example:
$hosts = array(
"server1",
"server2"
);
$cb = new Couchbase($hosts,
"user",
"pass",
"bucket",
true);
With this method of building the connection, the client will try each of the hosts specified in the order specified until it either connects with and establishes a connection to a cluster or it runs out of hosts to try.
API Call | $object->addServer($host, $port [, $weight ])
|
---|---|
Asynchronous | no |
Description | Add a server to the connection pool |
Returns | scalar ( Binary object ) |
Arguments | |
string $host | Addresses a server by hostname or numeric IP address |
integer $port | Specifies a TCP port number |
integer $weight | Defines the relative weight of a server in the connection pool. |
API Call | $object->getOption($option)
|
---|---|
Asynchronous | no |
Description | Retrieve an option |
Returns | scalar ( Binary object ) |
Arguments | |
int $option | Option controlling connection or server behavior |
API Call | $object->setOption($option, $mixed)
|
---|---|
Asynchronous | no |
Description | Specify an option |
Returns | boolean ( Boolean (true/false) ) |
Arguments | |
int $option | Option controlling connection or server behavior |
scalar $mixed | Option value (constant, number, or string) |
API Call | $object->add($key, $value [, $expiry ] [, $persistto ] [, $replicateto ])
|
---|---|
Asynchronous | no |
Description | Add a value with the specified key that does not already exist. Will fail if the key/value pair already exist. |
Returns | scalar ; supported values: |
COUCHBASE_E2BIG
|
|
COUCHBASE_EINTERNAL
|
|
COUCHBASE_ENOMEM
|
|
COUCHBASE_ETMPFAIL
|
|
COUCHBASE_NOT_MY_VBUCKET
|
|
COUCHBASE_NOT_STORED
|
|
docid
|
|
Arguments | |
string $key | Document ID used to identify the value |
object $value | Value to be stored |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
$persistto | Specify the number of nodes on which the document must be persisted to before returning. |
$replicateto | Specify the number of nodes on which the document must be replicated to before returning |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
API Call | $object->replace($key, $value [, $expiry ] [, $casunique ] [, $persistto ] [, $replicateto ])
|
---|---|
Asynchronous | no |
Description | Update an existing key with a new value |
Returns | scalar ; supported values: |
COUCHBASE_E2BIG
|
|
COUCHBASE_ENOMEM
|
|
COUCHBASE_ETMPFAIL
|
|
COUCHBASE_KEY_ENOENT
|
|
COUCHBASE_NOT_MY_VBUCKET
|
|
COUCHBASE_NOT_STORED
|
|
docid
|
|
Arguments | |
string $key | Document ID used to identify the value |
object $value | Value to be stored |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
$casunique | Unique value used to verify a key/value combination |
$persistto | Specify the number of nodes on which the document must be persisted to before returning. |
$replicateto | Specify the number of nodes on which the document must be replicated to before returning |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
API Call | $object->set($key, $value [, $expiry ] [, $casunique ] [, $persistto ] [, $replicateto ])
|
---|---|
Asynchronous | no |
Description | Store a value using the specified key, whether the key already exists or not. Will overwrite a value if the given key/value already exists. |
Returns | scalar ; supported values: |
COUCHBASE_E2BIG
|
|
COUCHBASE_ENOMEM
|
|
COUCHBASE_ETMPFAIL
|
|
COUCHBASE_NOT_MY_VBUCKET
|
|
COUCHBASE_NOT_STORED
|
|
docid
|
|
Arguments | |
string $key | Document ID used to identify the value |
object $value | Value to be stored |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
$casunique | Unique value used to verify a key/value combination |
$persistto | Specify the number of nodes on which the document must be persisted to before returning. |
$replicateto | Specify the number of nodes on which the document must be replicated to before returning |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
API Call | $object->addByKey($master_key, $key, $value [, $expiry ])
|
---|---|
Asynchronous | no |
Description | Store a value with a server key |
Returns | scalar ( Binary object ) |
Arguments | |
$master_key | Master key used for consistent server references |
string $key | Document ID used to identify the value |
object $value | Value to be stored |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
API Call | $object->setByKey($master_key, $key, $value [, $expiry ])
|
---|---|
Asynchronous | no |
Description | Store a value using the specified key, whether the key already exists or not. Will overwrite a value if the given key/value already exists. |
Returns | scalar ( Binary object ) |
Arguments | |
$master_key | Master key used for consistent server references |
string $key | Document ID used to identify the value |
object $value | Value to be stored |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
API Call | $object->setMultiByKey($array [, $expiry ])
|
---|---|
Asynchronous | no |
Description | Set multiple key/value items at once on a specific server |
Returns | scalar ( Binary object ) |
Arguments | |
array $array | List of things |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
API Call | $object->setMulti($kvarray [, $expiry ])
|
---|---|
Asynchronous | no |
Description | Set multiple key/value items at once; updates supplied array for successful operation. |
Returns | boolean ; supported values: |
COUCHBASE_E2BIG
|
|
COUCHBASE_ENOMEM
|
|
COUCHBASE_ETMPFAIL
|
|
COUCHBASE_NOT_MY_VBUCKET
|
|
COUCHBASE_NOT_STORED
|
|
COUCHBASE_SUCCESS
|
|
Arguments | |
array $kvarray | List of key/value pairs |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
API Call | $object->flush()
|
---|---|
Asynchronous | no |
Description | Deletes all values from the corresponding bucket |
Returns | boolean ; supported values: |
COUCHBASE_ETMPFAIL
|
|
COUCHBASE_NOT_MY_VBUCKET
|
|
COUCHBASE_SUCCESS
|
|
Arguments | |
None | |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
API Call | $object->get($key [, $callback ] [, $casunique ])
|
---|---|
Asynchronous | no |
Description | Get one or more key values |
Returns | scalar ; supported values: |
COUCHBASE_KEY_ENOENT
|
|
object
|
|
Arguments | |
string $key | Document ID used to identify the value |
mixed $callback | Callback function or method to be called |
$casunique | Unique value used to verify a key/value combination |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
API Call | $object->getMulti($keycollection [, $casarray ])
|
---|---|
Asynchronous | no |
Description | Get one or more key values |
Returns | array ( Array of key/value pairs for each document, or key/error condition for each failure ) |
Arguments | |
array $keycollection | One or more keys used to reference a value |
array $casarray | Array of unique values used to verify a key/value combination |
API Call | $object->getDelayed($keyn [, $with_cas ] [, $callback ])
|
---|---|
Asynchronous | yes |
Description | Get one or more key values |
Returns | boolean ; supported values: |
COUCHBASE_KEY_ENOENT
|
|
COUCHBASE_SUCCESS
|
|
Arguments | |
array $keyn | One or more keys used to reference a value |
boolean $with_cas | Whether to return the CAS value for a document |
mixed $callback | Callback function or method to be called |
API Call | $object->fetch($key [, $keyn ])
|
---|---|
Asynchronous | yes |
Description | Fetch the next delayed result set document |
Returns | array ( An array of the next document retrieved, or NULL if no more documents ) |
Arguments | |
string $key | Document ID used to identify the value |
array $keyn | One or more keys used to reference a value |
API Call | $object->fetchAll($key [, $keyn ])
|
---|---|
Asynchronous | yes |
Description | Fetch all the delayed result set documents |
Returns | array ( An array of all the remaining documents retrieved, or NULL if no more documents ) |
Arguments | |
string $key | Document ID used to identify the value |
array $keyn | One or more keys used to reference a value |
API Call | $object->getByKey($master_key, $key [, $cache_callback ] [, $casunique ])
|
---|---|
Asynchronous | no |
Description | Get one or more key values |
Returns | scalar ( Binary object ) |
Arguments | |
$master_key | Master key used for consistent server references |
string $key | Document ID used to identify the value |
scalar $cache_callback | Function to be called in the form function($key, $value) |
$casunique | Unique value used to verify a key/value combination |
API Call | $object->getDelayedByKey($master_key, $keyn [, $with_cas ] [, $callback ])
|
---|---|
Asynchronous | no |
Description | Get one or more key values |
Returns | scalar ( Binary object ) |
Arguments | |
$master_key | Master key used for consistent server references |
array $keyn | One or more keys used to reference a value |
boolean $with_cas | Whether to return the CAS value for a document |
mixed $callback | Callback function or method to be called |
API Call | $object->getMultiByKey($master_key, $keyn [, $cas_token ] [, $flags ])
|
---|---|
Asynchronous | no |
Description | Get one or more key values |
Returns | scalar ( Binary object ) |
Arguments | |
$master_key | Master key used for consistent server references |
array $keyn | One or more keys used to reference a value |
float $cas_token | CAS token for conditional operations |
$flags | Flags for storage options. Flags are ignored by the server byt preserved for use by the client. |
API Call | $object->getResultCode()
|
---|---|
Asynchronous | no |
Description | Returns the result code for the last operation |
Returns | () |
Arguments | |
None |
API Call | $object->getResultMessage()
|
---|---|
Asynchronous | no |
Description | Returns the result message for the last operation |
Returns | () |
Arguments | |
None |
API Call | $object->getVersion()
|
---|---|
Asynchronous | no |
Description | Returns the versions of all servers in the server pool |
Returns | array ; supported values: |
array
|
|
Arguments | |
None |
API Call | $object->append($key, $value [, $expiry ] [, $casunique ] [, $persistto ] [, $replicateto ])
|
---|---|
Asynchronous | no |
Description | Append a value to an existing key |
Returns | scalar ; supported values: |
COUCHBASE_E2BIG
|
|
COUCHBASE_ENOMEM
|
|
COUCHBASE_ETMPFAIL
|
|
COUCHBASE_KEY_ENOENT
|
|
COUCHBASE_NOT_MY_VBUCKET
|
|
COUCHBASE_NOT_STORED
|
|
docid
|
|
Arguments | |
string $key | Document ID used to identify the value |
object $value | Value to be stored |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
$casunique | Unique value used to verify a key/value combination |
$persistto | Specify the number of nodes on which the document must be persisted to before returning. |
$replicateto | Specify the number of nodes on which the document must be replicated to before returning |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
API Call | $object->cas($casunique, $key, $value [, $expiry ])
|
---|---|
Asynchronous | no |
Description | Compare and set a value providing the supplied CAS key matches |
Returns | boolean ; supported values: |
COUCHBASE_E2BIG
|
|
COUCHBASE_ENOMEM
|
|
COUCHBASE_ETMPFAIL
|
|
COUCHBASE_KEY_EEXISTS
|
|
COUCHBASE_KEY_ENOENT
|
|
COUCHBASE_NOT_MY_VBUCKET
|
|
COUCHBASE_NOT_STORED
|
|
COUCHBASE_SUCCESS
|
|
Arguments | |
$casunique | Unique value used to verify a key/value combination |
string $key | Document ID used to identify the value |
object $value | Value to be stored |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
API Call | $object->decrement($key, $offset)
|
---|---|
Asynchronous | no |
Description | Decrement the value of an existing numeric key. The Couchbase Server stores numbers as unsigned values. Therefore the lowest you can decrement is to zero. |
Returns | scalar ; supported values: |
COUCHBASE_DELTA_BADVAL
|
|
COUCHBASE_E2BIG
|
|
COUCHBASE_ENOMEM
|
|
COUCHBASE_ETMPFAIL
|
|
COUCHBASE_KEY_ENOENT
|
|
COUCHBASE_NOT_MY_VBUCKET
|
|
COUCHBASE_NOT_STORED
|
|
scalar
|
|
Arguments | |
string $key | Document ID used to identify the value |
$offset | Integer offset value to increment/decrement (default 1) |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
API Call | $object->delete($key [, $casunique ])
|
---|---|
Asynchronous | no |
Description | Delete a key/value |
Returns | scalar ; supported values: |
COUCHBASE_ETMPFAIL
|
|
COUCHBASE_KEY_ENOENT
|
|
COUCHBASE_NOT_MY_VBUCKET
|
|
COUCHBASE_NOT_STORED
|
|
docid
|
|
Arguments | |
string $key | Document ID used to identify the value |
$casunique | Unique value used to verify a key/value combination |
API Call | $object->increment($key [, $offset ] [, $create ] [, $expiry ] [, $initial ])
|
---|---|
Asynchronous | no |
Description | Increment the value of an existing numeric key. Couchbase Server stores numbers as unsigned numbers, therefore if you try to increment an existing negative number, it will cause an integer overflow and return a non-logical numeric result. If a key does not exist, this method will initialize it with the zero or a specified value. |
Returns | scalar ; supported values: |
COUCHBASE_DELTA_BADVAL
|
|
COUCHBASE_E2BIG
|
|
COUCHBASE_ENOMEM
|
|
COUCHBASE_ETMPFAIL
|
|
COUCHBASE_KEY_ENOENT
|
|
COUCHBASE_NOT_MY_VBUCKET
|
|
COUCHBASE_NOT_STORED
|
|
scalar
|
|
Arguments | |
string $key | Document ID used to identify the value |
$offset | Integer offset value to increment/decrement (default 1) |
boolean $create | Create the document if it does not already exist |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
boolean $initial | Initial value for the document |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
API Call | $object->prepend($key, $value [, $expiry ] [, $casunique ] [, $persistto ] [, $replicateto ])
|
---|---|
Asynchronous | no |
Description | Prepend a value to an existing key |
Returns | scalar ; supported values: |
COUCHBASE_E2BIG
|
|
COUCHBASE_ENOMEM
|
|
COUCHBASE_ETMPFAIL
|
|
COUCHBASE_KEY_ENOENT
|
|
COUCHBASE_NOT_MY_VBUCKET
|
|
COUCHBASE_NOT_STORED
|
|
docid
|
|
Arguments | |
string $key | Document ID used to identify the value |
object $value | Value to be stored |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
$casunique | Unique value used to verify a key/value combination |
$persistto | Specify the number of nodes on which the document must be persisted to before returning. |
$replicateto | Specify the number of nodes on which the document must be replicated to before returning |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
API Call | $object->appendByKey($master_key, $key, $value [, $expiry ])
|
---|---|
Asynchronous | no |
Description | Append to a key on a specific server |
Returns | scalar ( Binary object ) |
Arguments | |
$master_key | Master key used for consistent server references |
string $key | Document ID used to identify the value |
object $value | Value to be stored |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
API Call | $object->prependByKey($master_key, $key, $value)
|
---|---|
Asynchronous | no |
Description | Prepend a value to a key on a specific server |
Returns | scalar ( Binary object ) |
Arguments | |
$master_key | Master key used for consistent server references |
string $key | Document ID used to identify the value |
object $value | Value to be stored |
API Call | $object->replaceByKey($master_key, $key, $value [, $expiry ])
|
---|---|
Asynchronous | no |
Description | Replace a value on a specific server |
Returns | scalar ( Binary object ) |
Arguments | |
$master_key | Master key used for consistent server references |
string $key | Document ID used to identify the value |
object $value | Value to be stored |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
API Call | $object->deleteByKey($master_key, $key)
|
---|---|
Asynchronous | no |
Description | Delete a key/value on a specific server |
Returns | scalar ; supported values: |
COUCHBASE_ETMPFAIL
|
|
COUCHBASE_KEY_ENOENT
|
|
COUCHBASE_NOT_MY_VBUCKET
|
|
COUCHBASE_NOT_STORED
|
|
docid
|
|
Arguments | |
$master_key | Master key used for consistent server references |
string $key | Document ID used to identify the value |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
API Call | $object->casByKey($casunique, $master_key, $key, $value [, $expiry ])
|
---|---|
Asynchronous | no |
Description | Compare and set a value providing the supplied CAS key matches |
Returns | scalar ( Binary object ) |
Arguments | |
$casunique | Unique value used to verify a key/value combination |
$master_key | Master key used for consistent server references |
string $key | Document ID used to identify the value |
object $value | Value to be stored |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
API Call | $object->touch($key, $expiry)
|
---|---|
Asynchronous | no |
Description | Update the expiry time of an item |
Returns | boolean ; supported values: |
COUCHBASE_ENOMEM
|
|
COUCHBASE_ETMPFAIL
|
|
COUCHBASE_KEY_ENOENT
|
|
COUCHBASE_NOT_MY_VBUCKET
|
|
COUCHBASE_NOT_STORED
|
|
COUCHBASE_SUCCESS
|
|
Arguments | |
string $key | Document ID used to identify the value |
$expiry | Expiry time for key. Values larger than 30*24*60*60 seconds (30 days) are interpreted as absolute times (from the epoch). |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
API Call | $object->getStats()
|
---|---|
Asynchronous | no |
Description | Get the database statistics |
Returns | array ; supported values: |
COUCHBASE_EINTERNAL
|
|
COUCHBASE_ERROR
|
|
array
|
|
Arguments | |
None | |
Errors | |
CouchbaseAuthenticationException |
Authentication to the Couchbase cluster failed |
CouchbaseException |
Base exception class for all Couchbase exceptions |
CouchbaseIllegalKeyException |
The key provided is not a legal key identifier |
CouchbaseLibcouchbaseException |
An error occurred within the libcouchbase library used by th PHP extension |
CouchbaseServerException |
An error occurred within the Couchbase cluster |
The following sections provide release notes for individual release versions of Couchbase Client Library PHP. To browse or submit new issues, see Couchbase Client Library PHP Issues Tracker.
New Features and Behavior Changes in 1.0.5
Allow for multiple hosts to be specified either via an array or a semicolon delimited list
This feature will configure the client library to automatically select another node from the cluster if the first node specified is down.
Fixes in 1.0.5
PCBC-77: Do not attempt to decompress uncompressed JSON.
This change allows for interoperability between the Java client library and the PHP client library, even though the flags may be slightly different between the two.
PCBC-75: Correctly free persistent structures.
Prior to this change, in some cases the client could encounter a segmentation fault while trying to use persistent connections.
This is a bugfix release of the Couchbase PHP SDK.
Fixes in 1.0.4
PCBC-65: Implement getResultMessage() and get_result_message()
PCBC-67: Add preserve_order flag to getMulti()
PCBC-66: null terminate keys in getMulti() responses
This is a bugfix release of the Couchbase PHP SDK.
Fixes in 1.0.3
This is a bugfix release of the Couchbase PHP SDK.
Fixes in 1.0.2
Fixed PCBC-62 (Extension reports wrong version).
Fixed PCBC-54 (Converting numbers in responses).
This is a bugfix release of the Couchbase PHP SDK.
Fixes in 1.0.1
Fixed build on Windows.
Fixed argument parsing for ::increment().
This is the first stable release of the Couchbase PHP SDK.
New Features and Behavior Changes in 1.0.0
Fixes in 1.0.0
Fixed tests, various segfaults and memory leaks.
Fixed naming of constants and features.
Renamed version() method and function to Couchbase::getVersion and couchbase_get_version() respectively.
Fixed PCBC-37 (Segfault when invalid hostname is provided).
Update compatibility with more recent libcouchbase releases.
Allow creation of non-existent keys with arithmetic calls.