찾다

Tyrant文件夹里的文件

Common.php

<?php/*** Tokyo Tyrant network API for PHP* * Copyright (c) 2009 Bertrand Mansion <bmansion@mamasam.com>* * Permission is hereby granted, free of charge, to any person obtaining a copy* of this software and associated documentation files (the "Software"), to deal* in the Software without restriction, including without limitation the rights* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell* copies of the Software, and to permit persons to whom the Software is* furnished to do so, subject to the following conditions:* * The above copyright notice and this permission notice shall be included in* all copies or substantial portions of the Software.* * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN* THE SOFTWARE.* * @package    Tyrant* @author     Bertrand Mansion <bmansion@mamasam.com>* @license    http://www.opensource.org/licenses/mit-license.php MIT License* @link       http://mamasam.indefero.net/p/tyrant/*/require_once dirname(__FILE__).'/../Tyrant.php';require_once dirname(__FILE__).'/Exception.php';/*** Abstract base class for all types of database connections** This base class is mostly here to avoid duplication of code since * databases share common functions. It** @package    Tyrant* @author     Bertrand Mansion <bmansion@mamasam.com>*/abstract class Tyrant_Common implements ArrayAccess, Countable, Iterator{    protected $socket;    abstract function put($key, $value);    abstract function get($key);    public function __construct(&$socket)    {        $this->socket =& $socket;    }    /**    * Close the connection to TokyoTyrant    */    public function disconnect()    {        if (is_resource($this->socket)) {            socket_close($this->socket);            $this->socket = null;        }    }    /**    * Returns the connection socket    * @return resource  Connection socket    */    public function &socket()    {        return $this->socket;    }    /**    * Removes a record    *     * @param    string  Specifies the primary key    * @return   bool    True when successful, false otherwise    */    public function out($key)    {        $cmd = pack('CCN', 0xC8, 0x20, strlen($key)) . $key;        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }                return true;    }    /**    * Gets the size of the value of a record    *    * @param    string  Specifies the key    * @return   int|false   Number with size or false otherwise    */    public function vsiz($key)    {        $cmd = pack("CCN", 0xC8, 0x38, strlen($key)) . $key;        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        return $this->_recvInt32();    }    /**    * Initializes the iterator    *    * The iterator is used in order to access the key of every record     * stored in a database.    *    * @return   bool    True when successful, false otherwise    */    public function iterinit()    {        $cmd = pack("CC", 0xC8, 0x50);        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        return true;    }    /**    * Gets the next key of the iterator    *    * It is possible to access every record by iteration of     * calling this method. It is allowed to update or remove     * records whose keys are fetched while the iteration.    * However, it is not assured if updating the database is     * occurred while the iteration. Besides, the order of this     * traversal access method is arbitrary, so it is not assured     * that the order of storing matches the one of the traversal     * access.    *    * @return   mixed   Either the next key when successful, false if no more records are available    */    public function iternext()    {        $cmd = pack("CC", 0xC8, 0x51);        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        $ksiz = $this->_recvInt32();        if ($ksiz === false) {            return false;        }        $kref = $this->_recv($ksiz);        return $kref;    }    /**    * Gets forward matching keys    *    * The return value is an array of the keys of the     * corresponding records. This method does never fail and return     * an empty array even if no record corresponds. Note that this     * method may be very slow because every key in the database is     * scanned.    *    * @param    string  Prefix of the corresponding keys    * @param    int     Maximum number of keys to be fetched. If it    *                   is not defined or negative, no limit is specified.    * @return   array   An array of found primary keys    */    public function fwmkeys($prefix, $max = null)    {        $keys = array();        if (empty($max) || $max < 0) {            $max = (1<<31);        }        $cmd = pack("CCNN", 0xC8, 0x58, strlen($prefix), $max) . $prefix;        $code = $this->_send($cmd);        if ($code !== 0) {            return $keys;        }        $knum = $this->_recvInt32();        if ($knum === false) {            return $keys;        }        for ($i = 0; $i < $knum; $i++) {            $ksiz = $this->_recvInt32();            if ($ksiz === false) {                return $keys;            }            $kref = $this->_recv($ksiz);            $keys[] = $kref;        }        return $keys;    }    /**    * Synchronizes updated contents with the file and the device    * @return   bool    True when successful, false otherwise    */    public function sync()    {        $cmd = pack('CC', 0xC8, 0x70);        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        return true;    }    /**    * Optimize the database file    * @return   bool    True when successful, false otherwise    */    public function optimize($params = "")    {        $cmd = pack('CCN', 0xC8, 0x71, strlen($params)) . $params;        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        return true;    }    /**    * Remove all records    * @return   bool    True when successful, false otherwise    */    public function vanish()    {        $cmd = pack('CC', 0xC8, 0x72);        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        return true;    }    /**    * Copy the database file    *    * The database file is assured to be kept synchronized and not modified     * while the copying or executing operation is in progress.    * So, this method is useful to create a backup file of the database file.    *    * @param    string  Specifies the path of the destination file.    *                   If it begins with `@', the trailing substring     *                   is executed as a command line.    * @return   True if successful, false otherwise.    */    public function copy($path)    {        $cmd = pack('CCN', 0xC8, 0x73, strlen($path)) . $path;        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        return true;    }    /**    * Restore the database with update log    *    * @param    Specifies the path of the update log directory    * @param    Specifies the beginning time stamp in microseconds    * @param    Specifies options by bitwise-or:    *           - Tyrant::ROCHKCON for consistency checking    * @return   True if successful, false otherwise.    */    public function restore($path, $msec, $opts = 0)    {        $cmd = pack('CCN', 0xC8, 0x74, strlen($path)) .                 $this->_pack64($msec) . $opts . $path;        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        return true;    }    /**    * Get the number of records    * @return int|false Number of records or false if something goes wrong    */    public function rnum()    {        $cmd = pack('CC', 0xC8, 0x80);        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        return $this->_recvInt64();    }    /**    * Get the size of the database    * @return mixed  Database size or false if something goes wrong    */    public function size()    {        $cmd = pack('CC', 0xC8, 0x81);        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        return $this->_recvInt64();    }    /**    * Get some statistics about the database    * @return   array   Array of statistics about the database    */    public function stat()    {        $cmd = pack('CC', 0xC8, 0x88);        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        $value = $this->_recv();        $value = explode("\n", trim($value));        $stats = array();        foreach ($value as $v) {            $v = explode("\t", $v);            $stats[$v[0]] = $v[1];        }        return $stats;    }    /**    * Call a versatile function for miscellaneous operations    *    * All databases support "putlist", "outlist", and "getlist".    * - putlist is to store records. It receives keys and values one     *   after the other, and returns an empty list.    * - outlist is to remove records. It receives keys, and returns     *   an empty list.    * - getlist is to retrieve records. It receives keys, and returns     *   values.    *    * Table database supports "setindex", "search", "genuid".    *    * @param    string  Specifies the name of the function    * @param    array   Specifies an array containing arguments    * @param    int     Specifies options by bitwise-or    *                   bitflag that can be Tyrant::MONOULOG to prevent     *                   writing to the update log    * @return   array|false     Values or false if something goes wrong    */    public function misc($name, Array $args = array(), $opts = 0)    {        $cmd = pack('CCNNN', 0xC8, 0x90, strlen($name), $opts,                 count($args)) . $name;        foreach ($args as $arg) {            $cmd .= pack('N', strlen($arg)) . $arg;        }        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        $rnum = $this->_recvInt32();        $res = array();        for ($i = 0; $i < $rnum; $i++) {            $esiz = $this->_recvInt32();            if ($esiz === false) {                return false;            }            $eref = $this->_recv($esiz);            if ($eref === false) {                return false;            }            $res[] = $eref;        }        return $res;    }    /**    * Call a function of the script language extension    *    * @param    string  Specifies the function name    * @param    string  Specifies the key. Defaults to an empty string.    * @param    string  Specifies the value. Defaults to an empty string.    * @param    int     Specifies options by bitwise-or:     *                   - Tyrant::XOLCKREC for record locking    *                   - Tyrant::XOLCKGLB for global locking    *                   Defaults to no option.    * @return   mixed   Value of the response or false on failure    */    public function ext($name, $key = '', $value = '', $opts = 0)    {        $cmd = pack('CCNNNN', 0xC8, 0x68, strlen($name), $opts,                 strlen($key), strlen($value)) .                 $name . $key . $value;        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        $vsiz = $this->_recvInt32();        if ($vsiz < 0) {            return false;        }        $vbuf = $this->_recv($vsiz);        return $vbuf;    }    protected function _socketWrite($cmd)    {        $len = strlen($cmd);        $offset = 0;        while ($offset < $len) {            $sent = socket_write($this->socket, substr($cmd, $offset), $len-$offset);            if ($sent === false) {                return false;            }            $offset += $sent;        }        return ($offset < $len) ? false : true;    }    protected function _send($cmd)    {        $status = $this->_socketWrite($cmd);        if ($status === false) {            return false;        }        $code = $this->_recvCode();        if ($code === false) {            return false;        }        return $code;    }    protected function _recv($len = null)    {        if (is_null($len)) {            $len = $this->_recvInt32();            if ($len === false) {                return false;            }        }        if ($len < 1) {            return "";        }        $str = "";        if (($rec = socket_recv($this->socket, $str, $len, 0)) <= 0) {            return false;        }        if (strlen($str) == $len) {            return $str;        }        $len -= strlen($str);        while ($len > 0) {            $tstr = "";            if (($rec = socket_recv($this->socket, $tstr, $len, 0)) <= 0) {                return false;            }            $len -= strlen($tstr);            $str .= $tstr;        }        return $str;    }    protected function _recvCode()    {        if (($rbuf = $this->_recv(1)) !== false) {            $c = unpack("C", $rbuf);            if (!isset($c[1])) {                return false;            }            return $c[1];        }        return false;    }    protected function _recvInt32()    {        if (($rbuf = $this->_recv(4)) !== false) {            $num = unpack("N", $rbuf);            if (!isset($num[1])) {                return false;            }            $size = unpack("l", pack("l", $num[1]));            return $size[1];        }        return false;    }    protected function _recvInt64()    {        if (($rbuf = $this->_recv(8)) !== false) {            return $this->_unpack64($rbuf);        }        return false;    }    /**    * Portability function to pack a x64 value with PHP limitations    * @return   mixed   Packed number    */    protected function _pack64($v)    {        // x64        if (PHP_INT_SIZE >= 8) {            $v = (int)$v;            return pack ("NN", $v>>32, $v&0xFFFFFFFF);        }        // x32, int        if (is_int($v)) {            return pack("NN", $v < 0 ? -1 : 0, $v);        }        // x32, bcmath            if (function_exists("bcmul")) {            if (bccomp($v, 0) == -1) {                $v = bcadd("18446744073709551616", $v);            }            $h = bcdiv($v, "4294967296", 0);            $l = bcmod($v, "4294967296");            return pack ("NN", (float)$h, (float)$l); // conversion to float is intentional; int would lose 31st bit        }        // x32, no-bcmath        $p = max(0, strlen($v) - 13);        $lo = abs((float)substr($v, $p));        $hi = abs((float)substr($v, 0, $p));        $m = $lo + $hi*1316134912.0; // (10 ^ 13) % (1 << 32) = 1316134912        $q = floor($m/4294967296.0);        $l = $m - ($q*4294967296.0);        $h = $hi*2328.0 + $q; // (10 ^ 13) / (1 << 32) = 2328        if ($v < 0) {            if ($l == 0) {                $h = 4294967296.0 - $h;            } else {                $h = 4294967295.0 - $h;                $l = 4294967296.0 - $l;            }        }        return pack("NN", $h, $l);    }    /**    * Portability function to unpack a x64 value with PHP limitations    * @return   mixed   Might return a string of numbers or the actual value    */    protected function _unpack64($v)    {        list($hi, $lo) = array_values (unpack("N*N*", $v));        // x64        if (PHP_INT_SIZE >= 8) {            if ($hi < 0) $hi += (1<<32); // because php 5.2.2 to 5.2.5 is totally fucked up again            if ($lo < 0) $lo += (1<<32);            return ($hi<<32) + $lo;        }        // x32, int        if ($hi == 0) {            if ($lo > 0) {                return $lo;            }            return sprintf("%u", $lo);        } elseif ($hi == -1) {            // x32, int            if ($lo < 0) {                return $lo;            }            return sprintf("%.0f", $lo - 4294967296.0);        }        $neg = "";        $c = 0;        if ($hi < 0) {            $hi = ~$hi;            $lo = ~$lo;            $c = 1;            $neg = "-";        }        $hi = sprintf ("%u", $hi);        $lo = sprintf ("%u", $lo);        // x32, bcmath        if (function_exists("bcmul")) {            return $neg . bcadd(bcadd($lo, bcmul($hi, "4294967296")), $c);        }        // x32, no-bcmath        $hi = (float)$hi;        $lo = (float)$lo;        $q = floor($hi/10000000.0);        $r = $hi - $q*10000000.0;        $m = $lo + $r*4967296.0;        $mq = floor($m/10000000.0);        $l = $m - $mq*10000000.0 + $c;        $h = $q*4294967296.0 + $r*429.0 + $mq;        $h = sprintf("%.0f", $h);        $l = sprintf("%07.0f", $l);        if ($h == "0") {            return $neg . sprintf("%.0f", (float)$l);        }        return $neg . $h . $l;    }    /**    * Store the current iterator key or false if no key is available    * @var string    */    protected $_current;    /**     * Rewind the Iterator to the first element.     * Similar to the reset() function for arrays in PHP     * @return void     */     public function rewind()    {        $this->iterinit();        $this->_current = $this->iternext();    }    /**    * Return the current element.     * Similar to the current() function for arrays in PHP     * @return mixed current element from the collection     */    public function current()    {        return $this->get($this->_current);    }    /**     * Return the identifying key of the current element.     * Similar to the key() function for arrays in PHP     * @return mixed either an integer or a string     */     public function key()    {        return $this->_current;    }    /**     * Move forward to next element.     * Similar to the next() function for arrays in PHP     * @return void     */     public function next()    {        $this->_current = $this->iternext();    }        /**     * Check if there is a current element after calls to rewind() or next().     * Used to check if we've iterated to the end of the collection     * @return boolean FALSE if there's nothing more to iterate over     */     public function valid()    {        return $this->_current !== false;    }        /**    * Returns whether the key exists    * @return boolean    */    public function offsetExists($offset)    {        return $this->vsiz($offset) !== false;    }    /**    * Returns the value associated with the key     * @return mixed    */    public function offsetGet($offset)    {        return $this->get($offset);    }    /**    * Sets a value for the key    * @return boolean   True if value was set successfully    */    public function offsetSet($offset, $value)    {        return $this->put($offset, $value);    }    /**    * Removes the value for the key    * @return void    */    public function offsetUnset($offset)    {        $this->out($offset);    }    /**    * Returns the number of records in the database    * @return int   Number of records    */    public function count()    {        return $this->rnum();    }}

Exception.php

<?php/*** Tokyo Tyrant network API for PHP* * Copyright (c) 2009 Bertrand Mansion <bmansion@mamasam.com>* * Permission is hereby granted, free of charge, to any person obtaining a copy* of this software and associated documentation files (the "Software"), to deal* in the Software without restriction, including without limitation the rights* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell* copies of the Software, and to permit persons to whom the Software is* furnished to do so, subject to the following conditions:* * The above copyright notice and this permission notice shall be included in* all copies or substantial portions of the Software.* * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN* THE SOFTWARE.* * @package    Tyrant* @author     Bertrand Mansion <bmansion@mamasam.com>* @license    http://www.opensource.org/licenses/mit-license.php MIT License* @link       http://mamasam.indefero.net/p/tyrant/*//*** Base class for Exceptions in Tyrant package** @package    Tyrant*/class Tyrant_Exception extends Exception { }

Query.php

<?php/*** Tokyo Tyrant network API for PHP** Copyright (c) 2009 Bertrand Mansion <bmansion@mamasam.com>** Permission is hereby granted, free of charge, to any person obtaining a copy* of this software and associated documentation files (the "Software"), to deal* in the Software without restriction, including without limitation the rights* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell* copies of the Software, and to permit persons to whom the Software is* furnished to do so, subject to the following conditions:** The above copyright notice and this permission notice shall be included in* all copies or substantial portions of the Software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN* THE SOFTWARE.** @package    Tyrant* @author     Bertrand Mansion <bmansion@mamasam.com>* @license    http://www.opensource.org/licenses/mit-license.php MIT License* @link       http://mamasam.indefero.net/p/tyrant/*//*** Query class for the RDBTable database queries** @package    Tyrant* @author     Bertrand Mansion <bmansion@mamasam.com>*/class Tyrant_Query{    /**    * Query arguments    * @var  array    */    protected $args = array();    /**    * Query condition: string is equal to    */    const QCSTREQ = 0;    /**    * Query condition: string is included in    */    const QCSTRINC = 1;    /**    * Query condition: string begins with    */    const QCSTRBW = 2;    /**    * Query condition: string ends with    */    const QCSTREW = 3;    /**    * Query condition: string includes all tokens in    */    const QCSTRAND = 4;    /**    * Query condition: string includes at least one token in    */    const QCSTROR = 5;    /**    * Query condition: string is equal to at least one token in    */    const QCSTROREQ = 6;    /**    * Query condition: string matches regular expressions of    */    const QCSTRRX = 7;    /**    * Query condition: number is equal to    */    const QCNUMEQ = 8;    /**    * Query condition: number is greater than    */    const QCNUMGT = 9;    /**    * Query condition: number is greater than or equal to    */    const QCNUMGE = 10;    /**    * Query condition: number is less than    */    const QCNUMLT = 11;    /**    * Query condition: number is less than or equal to    */    const QCNUMLE = 12;    /**    * Query condition: number is between two tokens of    */    const QCNUMBT = 13;    /**    * Query condition: number is equal to at least one token in    */    const QCNUMOREQ = 14;    /**    * Query condition: full-text search with the phrase of the expression    */    const QCFTSPH = 15;    /**    * Query condition: full-text search with all tokens in the expression    */    const QCFTSAND = 16;    /**    * Query condition: full-text search with at least one token in the expression    */    const QCFTSOR = 17;    /**    * Query condition: full-text search with the compound expression    */    const QCFTSEX = 18;    /**    * Query condition: negation flag    */    const QCNEGATE = 16777216;    /**    * Query condition: no index flag    */    const QCNOIDX = 33554432;    /**    * Order type: string ascending    */    const QOSTRASC = 0;    /**    * Order type: string descending    */    const QOSTRDESC = 1;    /**    * Order type: number ascending    */    const QONUMASC = 2;    /**    * Order type: number descending    */    const QONUMDESC = 3;    /**    * Add a query argument for "string is equal to column"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function is($name, $expr)    {        $this->addCond($name, self::QCSTREQ, $expr);    }    /**    * Add a query argument for "string is included in column"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function like($name, $expr)    {        $this->addCond($name, self::QCSTRINC, $expr);    }    /**    * Add a query argument for "string includes at least one token from column"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function has($name, $expr)    {        $this->addCond($name, self::QCSTROR, $expr);    }    /**    * Add a query argument for "string includes all tokens from column"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function hasAll($name, $expr)    {        $this->addCond($name, self::QCSTRAND, $expr);    }    /**    * Add a query argument for "string is equal to at least one token from column"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function isOne($name, $expr)    {        $this->addCond($name, self::QCSTROREQ, $expr);    }    /**    * Add a query argument for "string begins with"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function starts($name, $expr)    {        $this->addCond($name, self::QCSTRBW, $expr);    }    /**    * Add a query argument for "string ends with"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function ends($name, $expr)    {        $this->addCond($name, self::QCSTREW, $expr);    }    /**    * Add a query argument for "string matches regular expressions of"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function matches($name, $expr)    {        $this->addCond($name, self::QCSTRRX, $expr);    }    /**    * Add a query argument for "number is equal to"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function eq($name, $expr)    {        $this->addCond($name, self::QCNUMEQ, $expr);    }    /**    * Add a query argument for "number is greater than"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function gt($name, $expr)    {        $this->addCond($name, self::QCNUMGT, $expr);    }    /**    * Add a query argument for "number is greater than or equal to"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function gte($name, $expr)    {        $this->addCond($name, self::QCNUMGE, $expr);    }    /**    * Add a query argument for "number is less than"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function lt($name, $expr)    {        $this->addCond($name, self::QCNUMLT, $expr);    }    /**    * Add a query argument for "number is less than or equal to"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function lte($name, $expr)    {        $this->addCond($name, self::QCNUMLE, $expr);    }    /**    * Add a query argument for "number is between two tokens of"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function between($name, $expr)    {        $this->addCond($name, self::QCNUMBT, $expr);    }    /**    * Add a query argument for "number is equal to at least one token in"    * @param    string  Column to query upon    * @param    string  Value to search    */    public function eqOne($name, $expr)    {        $this->addCond($name, self::QCNUMOREQ, $expr);    }    /**    * Add a sort parameter for the query    * @param    string  Column to sort    * @param    string  'numeric' or 'literal'    * @param    string  'asc' or 'desc'    */    public function sortBy($name, $type = 'numeric', $direction = 'asc')    {        if ($type != 'numeric') {            $type = $direction != 'asc' ? self::QOSTRDESC : self::QOSTRASC;        } else {            $type = $direction != 'asc' ? self::QONUMDESC : self::QONUMASC;        }        $this->setOrder($name, $type);    }    /**    * Add a narrowing condition for the query.    * @param    string  Name of a column.  An empty string means the primary key.    * @param    int     Operation type, see class constants.    * @param    mixed   Operand exression.    */    public function addCond($name, $op, $expr)    {        $this->args[] = "addcond\0" . $name . "\0" . $op . "\0" . $expr;    }    /**    * Add a sort parameter for the query    * @param    string  Name of a column.    * @param    int     Sort type, see class constants.    */    public function setOrder($name, $type)    {        $this->args['order'] = "setorder\0" . $name . "\0" . $type;    }    /**    * Limit the number of records returned by the query    * @param    int     Maximum number of records returned    * @param    int     Number of records to skip    */    public function setLimit($max = -1, $skip = -1)    {        $this->args['limit'] = "setlimit\0" . $max . "\0" . $skip;    }    /**    * Return the query arguments    * @return   array   Query arguments    */    public function args()    {        return $this->args;    }}

RDB.php

<?php/*** Tokyo Tyrant network API for PHP* * Copyright (c) 2009 Bertrand Mansion <bmansion@mamasam.com>* * Permission is hereby granted, free of charge, to any person obtaining a copy* of this software and associated documentation files (the "Software"), to deal* in the Software without restriction, including without limitation the rights* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell* copies of the Software, and to permit persons to whom the Software is* furnished to do so, subject to the following conditions:* * The above copyright notice and this permission notice shall be included in* all copies or substantial portions of the Software.* * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN* THE SOFTWARE.* * @package    Tyrant* @author     Bertrand Mansion <bmansion@mamasam.com>* @license    http://www.opensource.org/licenses/mit-license.php MIT License* @link       http://mamasam.indefero.net/p/tyrant/*/require_once dirname(__FILE__).'/Common.php';/*** Hash and other types of database connection, all except the Table type** @package    Tyrant* @author     Bertrand Mansion <bmansion@mamasam.com>*/class Tyrant_RDB extends Tyrant_Common{    /**    * Unconditionally set key to value    * If a record with the same key exists in the database,     * it is overwritten.    *    * @param    string|int  Specifies the key.    * @param    mixed       A scalar value (or an object with __toString)    * @return   bool        True if successful, false otherwise    * @throws   Tyrant_Exception    */    public function put($key, $value)    {        $cmd = pack('CCNN', 0xC8, 0x10, strlen($key), strlen($value)) .                 $key . $value;        $code = $this->_send($cmd);        if ($code !== 0) {            throw new Tyrant_Exception("Put error");        }                return true;    }    /**    * Store a new record    * If a record with the same key exists in the database,    * this method has no effect.    *    * @param    string|int  Specifies the key.    * @param    mixed       A scalar value (or an object with __toString)    * @return   bool        True if successful, false otherwise    * @throws   Tyrant_Exception    */    public function putkeep($key, $value)    {        $cmd = pack('CCNN', 0xC8, 0x11, strlen($key), strlen($value)) .                 $key . $value;        $code = $this->_send($cmd);        if ($code !== 0) {            throw new Tyrant_Exception("Put error");        }                return true;    }    /**    * Append value to the existing value for key, or set key to    * value if it does not already exist.    *    * @param    string|int  Specifies the key.    * @param    mixed       A scalar value (or an object with __toString)    * @return   bool        True if successful, false otherwise    * @throws   Tyrant_Exception    */    public function putcat($key, $value)    {        $cmd = pack('CCNN', 0xC8, 0x12, strlen($key), strlen($value)) .                 $key . $value;        $code = $this->_send($cmd);        if ($code !== 0) {            throw new Tyrant_Exception("Put error");        }                return true;    }    /**    * Concatenate a value at the end of the existing record and     * shift it to the left    *    * @param    string|int  Specifies the key.    * @param    mixed       A scalar value (or an object with __toString)    * @return   bool        True if successful, false otherwise    * @throws   Tyrant_Exception    */    public function putshl($key, $value, $width)    {        $width = $width < 0 ? 0 : (int)$width;        $cmd = pack('CCNNN', 0xC8, 0x13, strlen($key), strlen($value), $width) .                 $key . $value;        $code = $this->_send($cmd);        if ($code !== 0) {            throw new Tyrant_Exception("Put error");        }                return true;    }    /**    * Set key to value without waiting for a server response    *    * @param    string|int  Specifies the key.    * @param    mixed       A scalar value (or an object with __toString)    * @return   bool        True if successful, false otherwise    * @throws   Tyrant_Exception    */    public function putnr($key, $value)    {        $cmd = pack('CCNN', 0xC8, 0x18, strlen($key), strlen($value)) .                 $key . $value;        $status = $this->_socketWrite($cmd);        if ($status === false) {            throw new Tyrant_Exception("Put error");        }        return true;    }    /**    * Get the value of a key from the server    *    * @param    string|int  Specifies the key.    * @return   string|null The value    */    public function get($key)    {        $cmd = pack('CCN', 0xC8, 0x30, strlen($key)) . $key;        $code = $this->_send($cmd);        if ($code !== 0) {            return null;        }        $value = $this->_recv();        return $value;    }    /**    * Retrieve records    * As a result of this method, keys existing in the database have     * the corresponding values and keys not existing in the database     * are removed.    *    * @param    array   Associative array containing the retrieval keys    *                   The array is given by reference so it will be     *                   filled with the values found.    * @return   int|false   Number of retrieved records or false on failure.    */    public function mget(&$recs)    {        $rnum = 0;        $cmd = "";        foreach ($recs as $key => $value) {            $cmd .= pack("N", strlen($key)) . $key;            $rnum++;        }        $cmd = pack("CCN", 0xC8, 0x31, $rnum) . $cmd;        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        $rnum = $this->_recvInt32();        if ($rnum === false) {            return false;        }        $recs = array();        for ($i = 0; $i < $rnum; $i++) {            $ksiz = $this->_recvInt32();            $vsiz = $this->_recvInt32();            if ($ksiz === false || $vsiz === false) {                return false;            }            $kref = $this->_recv($ksiz);            $vref = $this->_recv($vsiz);            $recs[$kref] = $vref;        }        return $rnum;    }    /**    * Add an integer to a record    * If the corresponding record exists, the value is treated as     * an integer and is added to the existing value. If no record exists,     * a new record is created with the value.    *     * @param    string      The key    * @param    int         The additional value    * @return   int|false   The summation value or false    * @throws   Tyrant_Exception    */    public function addInt($key, $num = 0)    {        $cmd = pack("CCNN", 0xC8, 0x60, strlen($key), (int)$num) . $key;        $code = $this->_send($cmd);        if ($code !== 0) {            throw new Tyrant_Exception("Could not addInt to ".$key);        }        return $this->_recvInt32();    }    /**    * Add a real number to a record    * If the corresponding record exists, the value is treated as     * a real number and is added to the existing value. If no record exists,     * a new record is created with the value.    *     * @param    string      The key    * @param    int         The additional value    * @return   int|false   The summation value or false    * @throws   Tyrant_Exception    */    public function addDouble($key, $num = 0)    {        $integ = substr($num, 0, strpos($num, '.'));        $fract = (abs($num) - floor(abs($num)))*1000000000000;        $cmd = pack('CCN', 0xC8, 0x61, strlen($key)) .                 $this->_pack64($integ) . $this->_pack64($fract) . $key;        $code = $this->_send($cmd);        if ($code !== 0) {            throw new Tyrant_Exception("AddDouble error");        }        $integ = $this->_recvint64();        $fract = $this->_recvint64();        return $integ + ($fract / 1000000000000);    }}

RDBTable.php

<?php/*** Tokyo Tyrant network API for PHP** Copyright (c) 2009 Bertrand Mansion <bmansion@mamasam.com>** Permission is hereby granted, free of charge, to any person obtaining a copy* of this software and associated documentation files (the "Software"), to deal* in the Software without restriction, including without limitation the rights* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell* copies of the Software, and to permit persons to whom the Software is* furnished to do so, subject to the following conditions:** The above copyright notice and this permission notice shall be included in* all copies or substantial portions of the Software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN* THE SOFTWARE.** @package    Tyrant* @author     Bertrand Mansion <bmansion@mamasam.com>* @license    http://www.opensource.org/licenses/mit-license.php MIT License* @link       http://mamasam.indefero.net/p/tyrant/*/require_once dirname(__FILE__).'/Common.php';require_once dirname(__FILE__).'/Query.php';/*** Table type database connection** @package    Tyrant* @author     Bertrand Mansion <bmansion@mamasam.com>*/class Tyrant_RDBTable extends Tyrant_Common{    /**    * index type: lexical string    */    const ITLEXICAL = 0;    /**    * index type: decimal string    */    const ITDECIMAL = 1;    /**    * index type: token inverted index    */    const ITTOKEN = 2;    /**    * index type: q-gram inverted index    */    const ITQGRAM = 3;    /**    * index type: optimize    */    const ITOPT = 9998;    /**    * index type: void    */    const ITVOID = 9999;    /**    * index type: keep existing index    */    const ITKEEP = 16777216; // 1 << 24    /**    * Store a record    * If a record with the same key exists in the database,    * it is overwritten.    *    * @param    string|int  Specifies the primary key.    * @param    array       Associative array containing key/values.    * @return   bool        True if successful, false otherwise    * @throws   Tyrant_Exception    */    public function put($key, $value)    {        $args = array($key);        foreach ($value as $ckey => $cvalue) {            $args[] = $ckey;            $args[] = $cvalue;        }        $rv = $this->misc('put', $args, 0);        if ($rv === false) {            throw new Tyrant_Exception("Put error");        }        return true;    }    /**    * Store a new record    * If a record with the same key exists in the database,    * this method has no effect.    *    * @param    string|int  Specifies the primary key.    * @param    array       Associative array containing key/values.    * @return   bool        True if successful, false otherwise    * @throws   Tyrant_Exception    */    public function putkeep($key, Array $values)    {        $args = array($key);        foreach ($values as $ckey => $cvalue) {            $args[] = $ckey;            $args[] = $cvalue;        }        $rv = $this->misc('putkeep', $args, 0);        if ($rv === false) {            throw new Tyrant_Exception("Put error");        }        return true;    }    /**    * Concatenate columns of the existing record    * If there is no corresponding record, a new record is created.    *    * @param    string|int  Specifies the primary key.    * @param    array       Associative array containing key/values.    * @return   bool        True if successful, false otherwise    * @throws   Tyrant_Exception    */    public function putcat($key, Array $values)    {        $args = array($key);        foreach ($values as $ckey => $cvalue) {            $args[] = $ckey;            $args[] = $cvalue;        }        $rv = $this->misc('putcat', $args, 0);        if ($rv === false) {            throw new Tyrant_Exception("Put error");        }        return true;    }    /**    * Retrieve a record    * @param    int|string  Specifies the primary key.    * @return   array|false If successful, the return value is an    *                       associative array, false if no record were found.    */    public function get($key)    {        $args = array($key);        $rv = $this->misc('get', $args, Tyrant::MONOULOG);        if ($rv === false) {            $rnum = $this->_recvInt32();            return null;        }        $cols = array();        $cnum = count($rv) - 1;        $i = 0;        while ($i < $cnum) {            $cols[$rv[$i]] = $rv[$i+1];            $i += 2;        }        return $cols;    }    /**    * Retrieve records    * Due to the protocol restriction, this method can not handle records    * with binary columns including the "\0" chracter.    *    * @param    array   Associative array containing the primary keys.    *                   As a result of this method, keys existing in the    *                   database have the corresponding columns and keys    *                   not existing in the database are removed.    * @return   int|false   If successful, the return value is the number of    *                       records found. False if none found.    */    public function mget(Array &$recs)    {        $rnum = 0;        $cmd = "";        foreach ($recs as $key => $value) {            $cmd .= pack("N", strlen($key)) . $key;            $rnum++;        }        $cmd = pack("CCN", 0xC8, 0x31, $rnum) . $cmd;        $code = $this->_send($cmd);        if ($code !== 0) {            return false;        }        $rnum = $this->_recvInt32();        if ($rnum === false) {            return false;        }        $recs = array();        for ($i = 0; $i < $rnum; $i++) {            $ksiz = $this->_recvInt32();            $vsiz = $this->_recvInt32();            if ($ksiz === false || $vsiz === false) {                return false;            }            $cols = array();            $kref = $this->_recv($ksiz);            $vref = $this->_recv($vsiz);            $cary = explode("\0", $vref);            $cnum = count($cary) - 1;            $j = 0;            while ($j < $cnum) {                $cols[$cary[$j]] = $cary[$j+1];                $j += 2;            }            $recs[$kref] = $cols;        }        return $rnum;    }    /**    * Set a column index    * @param    string  Name of a column.    *                   If the name of an existing index is specified,    *                   the index is rebuilt. An empty string means the    *                   primary key.    * @param    int     Specifies the index type:    *                   - Tyrant_RDBTable::ITLEXICAL for lexical string    *                   - Tyrant_RDBTable::ITDECIMAL for decimal string    *                   - Tyrant::ITOPT for optimizing the index    *                   - tyrant_RDBTable::ITVOID for removing the index    *                   If Tyrant_RDBTable::ITKEEP is added by bitwise-or and    *                   the index exists, this method merely returns failure.    *    * @return   bool    True if successful    * @throws   Tyrant_Exception    */    public function setindex($name, $type)    {        $args = array($name, $type);        $rv = $this->misc('setindex', $args, 0);        if ($rv === false) {            throw new Tyrant_Exception("Could not set index on ".$name);        }        return true;    }    /**    * Generate a unique ID number    * @return   int   The new unique ID number    * @throws   Tyrant_Exception    */    public function genuid()    {        $rv = $this->misc('genuid', array());        if ($rv === false) {            throw new Tyrant_Exception("Could not generate a new unique ID");        }        return $rv[0];    }    /**    * Execute a search    * This method does never fail and return an empty array even    * if no record corresponds.    *    * @param    object  A Tyrant_Query object    * @return   array   Array of the primary keys of records found.    */    public function search(Tyrant_Query $query)    {        $rv = $this->misc("search", $query->args(), Tyrant::MONOULOG);        return empty($rv) ? array() : $rv;    }    /**    * Remove each corresponding records    *    * @param    object  A Tyrant_Query object    * @return bool True if successful, false otherwise    */    public function searchOut(Tyrant_Query $query)    {        $args = $query->args();        $args[] = "out";        $rv = $this->misc("search", $args, 0);        return empty($rv) ? array() : $rv;    }    /**    * Get records corresponding to the search of a query object    * The return value is an array of associative arrays with column of    * the corresponding records. This method does never fail and return    * an empty array even if no record corresponds.    * Due to the protocol restriction, this method can not handle records    * with binary columns including the "\0" chracter.    *    * @param    object  A Tyrant_Query object    * @param    string|array    Array of column names to be fetched.    *                           An empty string returns the primary key.    *                           If it is left null, every column is fetched.    * @return   array   Array of records found    */    public function searchGet(Tyrant_Query $query, $names = null)    {        $args = $query->args();        if (is_array($names)) {            $args[] = "get\0" . implode("\0", $names);        } else {            $args[] = "get";        }        $rv = $this->misc("search", $args, Tyrant::MONOULOG);        if (empty($rv)) {            return array();        }        foreach ($rv as $i => $v) {            $cols = array();            $cary = explode("\0", $v);            $cnum = count($cary) - 1;            $j = 0;            while ($j < $cnum) {                $cols[$cary[$j]] = $cary[$j+1];                $j += 2;            }            $rv[$i] = $cols;        }        return $rv;    }    /**    * Get the count of corresponding records    *    * @param    object  A Tyrant_Query object    * @return   int     Count of corresponding records or 0 on failure    */    public function searchCount(Tyrant_Query $query)    {        $args = $query->args();        $args[] = "count";        $rv = $this->misc("search", $args, Tyrant::MONOULOG);        return empty($rv) ? 0 : $rv[0];    }}

与Tyrant同级目录的文件

Tyrant.php

<?php/*** Tokyo Tyrant network API for PHP* * Copyright (c) 2009 Bertrand Mansion <bmansion@mamasam.com>* * Permission is hereby granted, free of charge, to any person obtaining a copy* of this software and associated documentation files (the "Software"), to deal* in the Software without restriction, including without limitation the rights* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell* copies of the Software, and to permit persons to whom the Software is* furnished to do so, subject to the following conditions:* * The above copyright notice and this permission notice shall be included in* all copies or substantial portions of the Software.* * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN* THE SOFTWARE.* * @package    Tyrant* @author     Bertrand Mansion <bmansion@mamasam.com>* @license    http://www.opensource.org/licenses/mit-license.php MIT License* @link       http://mamasam.indefero.net/p/tyrant/*/require_once dirname(__FILE__).'/Tyrant/Exception.php';/*** Factory for Tokyo Tyrant connections** @package    Tyrant* @author     Bertrand Mansion <bmansion@mamasam.com>*/class Tyrant{    /**    * Scripting extension option for record locking    */    const XOLCKREC = 1;    /**    * scripting extension option for global locking    */    const XOLCKGLB = 2;    /**    * Misc function option for omission of the update log    */    const MONOULOG = 1;    /**    * Restore function option for consistency checking    */    const ROCHKCON = 1;    /**    * Keeps track of the connection objects    * Makes it possible to easily reuse a connection.    * @var  array    */    protected static $connections = array();    /**    * Current connection object    * @var object    */    protected static $connection;    /**    * Opens a connection to a Tokyo Tyrant server    * <code>    * try {    *     $tt = Tyrant::connect('localhost', 1978);    * } catch (Tyrant_Exception $e) {    *     echo $e->getMessage();    * }    * </code>    *    * @param    string  Server hostname or IP address    * @param    string  Server port    * @param    string  Optional existing connection id    * @return   object  Database connection    */    public static function connect($host = 'localhost', $port = '1978', $id = 0)    {        $id = implode(':', array($host, $port, $id));                // Check if connection already exists                if (isset(self::$connections[$id])) {            $connection =& self::$connections[$id];            return $connection;        }        // Start a new connection        $ip = gethostbyname($host);        $addr = ip2long($ip);        if (empty($addr)) {            throw new Tyrant_Exception("Host not found");        }        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);        if (!is_resource($socket)){            throw new Tyrant_Exception("Connection refused");        }        if (!socket_connect($socket, $addr, $port)) {            throw new Tyrant_Exception("Connection refused");        }        if (defined('TCP_NODELAY')) {            socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1);        } else {            // See http://bugs.php.net/bug.php?id=46360            socket_set_option($socket, SOL_TCP, 1, 1);        }        // Determine the database type        if (socket_write($socket, pack('CC', 0xC8, 0x88)) === false) {            throw new Tyrant_Exception("Unable to get database type");        }        $str = '';        if (socket_recv($socket, $str, 1, 0) === false) {            throw new Tyrant_Exception("Unable to get database type");        }        $c = unpack("C", $str);        if (!isset($c[1]) || $c[1] !== 0) {            throw new Tyrant_Exception("Unable to get database type");        }        $str = '';        if (socket_recv($socket, $str, 4, 0) === false) {            throw new Tyrant_Exception("Unable to get database type");        }        $num = unpack("N", $str);        if (!isset($num[1])) {            throw new Tyrant_Exception("Unable to get database type");        }        $size = unpack("l", pack("l", $num[1]));        $len = $size[1];        $str = '';        if (socket_recv($socket, $str, $len, 0) === false) {            throw new Tyrant_Exception("Unable to get database type");        }        $value = explode("\n", trim($str));        $stats = array();        foreach ($value as $v) {            $v = explode("\t", $v);            $stats[$v[0]] = $v[1];        }        if (!isset($stats['type'])) {            throw new Tyrant_Exception("Unable to get database type");        }                // Get the right interface for the database type                if ($stats['type'] == 'table') {            include_once dirname(__FILE__).'/Tyrant/RDBTable.php';            $conn = new Tyrant_RDBTable($socket);        } else {            include_once dirname(__FILE__).'/Tyrant/RDB.php';            $conn = new Tyrant_RDB($socket);        }        self::$connections[$id] =& $conn;        self::$connection = $conn;        return $conn;    }    /**    * Return the current connection    * The current connection is set using Tyrant::setConnection() and    * defaults to the last connection made    *    * @return   object|null     First connection in the stack    */    public function getConnection()    {        return self::$connection;    }    /**    * Changes the current connection    * @param    string  Server hostname or IP address    * @param    string  Server port    * @param    string  Optional existing connection id    * @return   object|null     First connection in the stack    */    public function setConnection($host = 'localhost', $port = '1978', $id = 0)    {        $id = implode(':', array($host, $port, $id));        self::$connection =& self::$connections[$id];    }    /**    * Disconnects and removes a connection    * @param    string  Server hostname or IP address    * @param    string  Server port    * @param    string  Optional existing connection id    */    public function disconnect($host = 'localhost', $port = '1978', $id = 0)    {        $id = implode(':', array($host, $port, $id));        if (isset(self::$connections[$id])) {            $connection =& self::$connections[$id];            $connection->disconnect();            unset(self::$connections[$id]);            return true;        }        return false;    }}

cache的使用类

cache_ttserver.php

<?php/** * TokyoCabinet数据库操作类 */require_once EXTENTION_PATH.'ttserver/Tyrant.php';require_once EXTENTION_PATH.'ttserver/Tyrant/Query.php';class cache_ttserver {    private $_conn = null;    public $_query = object;    /**     * 构造函数-创建TTSERVER连接对象     */    public function __construct($host , $port) {        $this->_conn = Tyrant::connect($host , $port);        $this->_query = new Tyrant_Query;    }    /**     * 写入一行记录     */    public function set($key , $value = null) {        $args_num = func_num_args();        if(is_array($key) && $args_num == 1) {            $values = $key;            foreach($values AS $_key => $_val) {                $this->_conn->put($_key , $_val);            }        } else {            return $this->_conn->put($key , $value);        }        return $this;    }        /**     * 读取一行记录     */    public function get($key) {        if(is_array($key)) {            $keys = $key;            $value = array();            foreach($keys AS $_key) {                $serialized_value = $this->_conn->get($_key);                $value[$_key] = $serialized_value;            }        } else {            $value = $this->_conn->get($key);        }        return $value;    }    /**     * 删除一行记录     */    public function remove($key) {        return $this->_conn->out($key);    }        /**     * 删除所有记录     */    public function removeAll() {        return $this->_conn->vanish();    }    /**     * 使用条件:TC HASH数据库     * 写入整形记录。若key存在,则更新记录,否则插入一条记录。     */    public function add($key , $increment) {        return $this->_conn->addInt($key , $increment);    }    /**     * 使用条件:TC TABLE数据库     * 获取一个连接对象遍历数据库中的所有键/值。     */    public function getIterator() {        return $this->_conn;    }    /**     * 获取记录数     */    public function rnum() {        return $this->_conn->rnum();    }        /**     * 使用条件:TC TABLE数据库     * 检索记录集,返回key     */    public function search() {        return $this->_conn->search($this->_query);    }        /**     * 使用条件:TC TABLE数据库     * 删除检索匹配的记录集     */    public function searchOut() {        return $this->_conn->searchOut($this->_query);    }        /**     * 使用条件:TC TABLE数据库     * 检索匹配的记录集,返回记录数组     */    public function searchGet($names = null) {        return $this->_conn->searchGet($this->_query, $names);    }        /**     * 使用条件:TC TABLE数据库     * 统计检索匹配的记录集个数     */    public function searchCount() {        return $this->_conn->searchCount($this->_query);    }}









성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
PHP의 현재 상태 : 웹 개발 동향을 살펴보십시오PHP의 현재 상태 : 웹 개발 동향을 살펴보십시오Apr 13, 2025 am 12:20 AM

PHP는 현대 웹 개발, 특히 컨텐츠 관리 및 전자 상거래 플랫폼에서 중요합니다. 1) PHP는 Laravel 및 Symfony와 같은 풍부한 생태계와 강력한 프레임 워크 지원을 가지고 있습니다. 2) Opcache 및 Nginx를 통해 성능 최적화를 달성 할 수 있습니다. 3) PHP8.0은 성능을 향상시키기 위해 JIT 컴파일러를 소개합니다. 4) 클라우드 네이티브 애플리케이션은 Docker 및 Kubernetes를 통해 배포되어 유연성과 확장 성을 향상시킵니다.

PHP 대 기타 언어 : 비교PHP 대 기타 언어 : 비교Apr 13, 2025 am 12:19 AM

PHP는 특히 빠른 개발 및 동적 컨텐츠를 처리하는 데 웹 개발에 적합하지만 데이터 과학 및 엔터프라이즈 수준의 애플리케이션에는 적합하지 않습니다. Python과 비교할 때 PHP는 웹 개발에 더 많은 장점이 있지만 데이터 과학 분야에서는 Python만큼 좋지 않습니다. Java와 비교할 때 PHP는 엔터프라이즈 레벨 애플리케이션에서 더 나빠지지만 웹 개발에서는 더 유연합니다. JavaScript와 비교할 때 PHP는 백엔드 개발에서 더 간결하지만 프론트 엔드 개발에서는 JavaScript만큼 좋지 않습니다.

PHP vs. Python : 핵심 기능 및 기능PHP vs. Python : 핵심 기능 및 기능Apr 13, 2025 am 12:16 AM

PHP와 Python은 각각 고유 한 장점이 있으며 다양한 시나리오에 적합합니다. 1.PHP는 웹 개발에 적합하며 내장 웹 서버 및 풍부한 기능 라이브러리를 제공합니다. 2. Python은 간결한 구문과 강력한 표준 라이브러리가있는 데이터 과학 및 기계 학습에 적합합니다. 선택할 때 프로젝트 요구 사항에 따라 결정해야합니다.

PHP : 웹 개발의 핵심 언어PHP : 웹 개발의 핵심 언어Apr 13, 2025 am 12:08 AM

PHP는 서버 측에서 널리 사용되는 스크립팅 언어이며 특히 웹 개발에 적합합니다. 1.PHP는 HTML을 포함하고 HTTP 요청 및 응답을 처리 할 수 ​​있으며 다양한 데이터베이스를 지원할 수 있습니다. 2.PHP는 강력한 커뮤니티 지원 및 오픈 소스 리소스를 통해 동적 웹 컨텐츠, 프로세스 양식 데이터, 액세스 데이터베이스 등을 생성하는 데 사용됩니다. 3. PHP는 해석 된 언어이며, 실행 프로세스에는 어휘 분석, 문법 분석, 편집 및 실행이 포함됩니다. 4. PHP는 사용자 등록 시스템과 같은 고급 응용 프로그램을 위해 MySQL과 결합 할 수 있습니다. 5. PHP를 디버깅 할 때 error_reporting () 및 var_dump ()와 같은 함수를 사용할 수 있습니다. 6. 캐싱 메커니즘을 사용하여 PHP 코드를 최적화하고 데이터베이스 쿼리를 최적화하며 내장 기능을 사용하십시오. 7

PHP : 많은 웹 사이트의 기초PHP : 많은 웹 사이트의 기초Apr 13, 2025 am 12:07 AM

PHP가 많은 웹 사이트에서 선호되는 기술 스택 인 이유에는 사용 편의성, 강력한 커뮤니티 지원 및 광범위한 사용이 포함됩니다. 1) 배우고 사용하기 쉽고 초보자에게 적합합니다. 2) 거대한 개발자 커뮤니티와 풍부한 자원이 있습니다. 3) WordPress, Drupal 및 기타 플랫폼에서 널리 사용됩니다. 4) 웹 서버와 밀접하게 통합하여 개발 배포를 단순화합니다.

과대 광고 : 오늘 PHP의 역할을 평가합니다과대 광고 : 오늘 PHP의 역할을 평가합니다Apr 12, 2025 am 12:17 AM

PHP는 현대적인 프로그래밍, 특히 웹 개발 분야에서 강력하고 널리 사용되는 도구로 남아 있습니다. 1) PHP는 사용하기 쉽고 데이터베이스와 완벽하게 통합되며 많은 개발자에게 가장 먼저 선택됩니다. 2) 동적 컨텐츠 생성 및 객체 지향 프로그래밍을 지원하여 웹 사이트를 신속하게 작성하고 유지 관리하는 데 적합합니다. 3) 데이터베이스 쿼리를 캐싱하고 최적화함으로써 PHP의 성능을 향상시킬 수 있으며, 광범위한 커뮤니티와 풍부한 생태계는 오늘날의 기술 스택에 여전히 중요합니다.

PHP의 약한 참고 자료는 무엇이며 언제 유용합니까?PHP의 약한 참고 자료는 무엇이며 언제 유용합니까?Apr 12, 2025 am 12:13 AM

PHP에서는 약한 참조가 약한 회의 클래스를 통해 구현되며 쓰레기 수집가가 물체를 되 찾는 것을 방해하지 않습니다. 약한 참조는 캐싱 시스템 및 이벤트 리스너와 같은 시나리오에 적합합니다. 물체의 생존을 보장 할 수 없으며 쓰레기 수집이 지연 될 수 있음에 주목해야합니다.

PHP의 __invoke 마법 방법을 설명하십시오.PHP의 __invoke 마법 방법을 설명하십시오.Apr 12, 2025 am 12:07 AM

\ _ \ _ 호출 메소드를 사용하면 객체를 함수처럼 호출 할 수 있습니다. 1. 객체를 호출 할 수 있도록 메소드를 호출하는 \ _ \ _ 정의하십시오. 2. $ obj (...) 구문을 사용할 때 PHP는 \ _ \ _ invoke 메소드를 실행합니다. 3. 로깅 및 계산기, 코드 유연성 및 가독성 향상과 같은 시나리오에 적합합니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

DVWA

DVWA

DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

SublimeText3 Linux 새 버전

SublimeText3 Linux 새 버전

SublimeText3 Linux 최신 버전

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.