# 自述文件
[](https://github.com/predis/predis/blob/HEAD/LICENSE)[](https://packagist.org/packages/predis/predis)[](https://packagist.org/packages/predis/predis)[](https://packagist.org/packages/predis/predis/stats)[](https://github.com/predis/predis/actions)
適用于 PHP 7.2 及更高版本的靈活且功能完整的[Redis客戶端。](http://redis.io/)
**注意:**您位于 Predis 不穩定分支的 README 文件中,專門用于開發未來版本。這意味著此分支上的代碼可能不穩定,并且可能會在沒有任何事先通知的情況下發生重大更改。不要在生產環境中使用它或使用它需要您自擔風險!
Predis 默認不需要任何額外的 C 擴展,但可以選擇與[ppiredis](https://github.com/nrk/phpiredis)配對,以降低[Redis RESP 協議](http://redis.io/topics/protocol)的序列化和解析開銷。
關于這個項目的更多細節可以在[常見問題](https://github.com/predis/predis/blob/HEAD/FAQ.md)中找到。
## [](http://packagist.p2hp.com/packages/predis/predis#user-content-main-features)主要特點
* 支持從**2.0**到**6.0**的 Redis 。
* 支持使用客戶端分片和可插入鍵空間分發器進行集群。
* 支持[redis-cluster](http://redis.io/topics/cluster-tutorial)(Redis >= 3.0)。
* 支持主從復制設置和[redis-sentinel](http://redis.io/topics/sentinel)。
* 使用可自定義的前綴策略對鍵進行透明的鍵前綴。
* 單個節點和集群上的命令流水線(僅限客戶端分片)。
* Redis 事務 (Redis >= 2.0) 和 CAS 操作 (Redis >= 2.2) 的抽象。
* `EVALSHA`Lua 腳本的抽象(Redis >= 2.6)和在or之間自動切換`EVAL`。
* 基于 PHP 迭代器的 、 和 (Redis >= 2.8`SCAN`)`SSCAN`的`ZSCAN`抽象。`HSCAN`
* 連接是由客戶端在第一個命令時延遲建立的,并且可以持久化。
* 可以通過 TCP/IP(也是 TLS/SSL 加密)或 UNIX 域套接字建立連接。
* 支持[Webdis](http://webd.is/)(同時需要`ext-curl`和`ext-phpiredis`)。
* 支持自定義連接類以提供不同的網絡或協議后端。
* 用于定義自定義命令并覆蓋默認命令的靈活系統。
## [](http://packagist.p2hp.com/packages/predis/predis#user-content-how-to-install-and-use-predis)如何*安裝*和使用 Predis
這個庫可以在[Packagist](http://packagist.org/packages/predis/predis)上找到,以便使用[Composer](http://packagist.org/about-composer)更輕松地管理項目依賴項。[GitHub 上提供](https://github.com/predis/predis/releases)了每個版本的壓縮檔案。
### [](http://packagist.p2hp.com/packages/predis/predis#user-content-loading-the-library)加載庫
Predis 依靠 PHP 的自動加載功能在需要時加載其文件,并符合[PSR-4 標準](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md)。當通過 Composer 管理依賴項時,自動加載會自動處理,但也可以在缺少任何自動加載工具的項目或腳本中利用其自己的自動加載器:
~~~
// 如果 Predis 在您的“include_path”中不可用,則添加一個基本路徑。
需要 'Predis/Autoloader.php';
Predis \ Autoloader :: register ();
~~~
### [](http://packagist.p2hp.com/packages/predis/predis#user-content-connecting-to-redis)連接到 Redis
在不傳遞任何連接參數的情況下創建客戶端實例時,Predis 假定`127.0.0.1`和`6379`作為默認主機和端口。操作的默認超時為`connect()`5 秒:
~~~
$ client = new Predis \ Client ();
$客戶端->設置( 'foo', 'bar');
$價值= $客戶->獲取( 'foo');
~~~
連接參數可以以 URI 字符串或命名數組的形式提供。后者是提供參數的首選方式,但當從非結構化或部分結構化的源中讀取參數時,URI 字符串會很有用:
~~~
// 使用命名數組傳遞的參數:
$ client = new Predis \ Client ([
'scheme' => 'tcp' ,
'host' => '10.0.0.1' ,
'port' => 6379 ,
]);
// 相同的參數集,使用 URI 字符串傳遞:
$ client = new Predis \ Client ( 'tcp://10.0.0.1:6379' );
~~~
可以通過添加`password`到參數集來訪問受密碼保護的服務器。在 Redis >= 6.0 上啟用 ACL時,用戶身份驗證需要`username`和。`password`
也可以使用 UNIX 域套接字連接到 Redis 的本地實例,在這種情況下,參數必須使用該`unix`方案并指定套接字文件的路徑:
~~~
$ client = new Predis \ Client ([ 'scheme' => 'unix' , 'path' => '/path/to/redis.sock' ]);
$ client = new Predis \ Client ( 'unix:/path/to/redis.sock' );
~~~
客戶端可以利用 TLS/SSL 加密連接到受保護的遠程 Redis 實例,而無需配置像 stunnel 這樣的 SSL 代理。這在連接到在各種云托管提供商上運行的節點時很有用。可以使用方案和通過參數傳遞`tls`的一組合適的[選項來啟用加密:](http://php.net/manual/context.ssl.php)`ssl`
~~~
// 命名的連接參數數組:
$ client = new Predis \ Client ([
'scheme' => 'tls' ,
'ssl' => [ 'cafile' => 'private.pem' , 'verify_peer' => true ] ,
]);
// 相同的參數集,但使用 URI 字符串:
$ client = new Predis \ Client ( 'tls://127.0.0.1?ssl[cafile]=private.pem&ssl[verify_peer]=1' );
~~~
還支持連接方案[`redis`](http://www.iana.org/assignments/uri-schemes/prov/redis)(的別名`tcp`)和[`rediss`](http://www.iana.org/assignments/uri-schemes/prov/rediss)(的別名`tls`),不同之處在于包含這些方案的 URI 字符串按照其各自的 IANA 臨時注冊文檔中描述的規則進行解析。
支持的連接參數的實際列表可能會因每個連接后端而異,因此建議參考其特定文檔或實現以了解詳細信息。
Predis 可以在提供一系列連接參數和適當的選項來指示客戶端如何聚合它們(集群、復制或自定義聚合邏輯)時聚合多個連接。為每個節點提供配置時,可以混合使用命名數組和 URI 字符串:
~~~
$ client = new Predis \ Client ([
'tcp://10.0.0.1?alias=first-node' , [ 'host' => '10.0.0.2' , 'alias' => 'second-node' ],
],[
'集群' => 'predis' ,
]);
~~~
有關更多詳細信息,請參閱本文檔的[聚合連接](http://packagist.p2hp.com/packages/predis/predis#user-content-aggregate-connections)部分。
與 Redis 的連接是惰性的,這意味著客戶端僅在需要時才連接到服務器。雖然建議讓客戶端在后臺做自己的事情,但有時仍希望控制連接何時打開或關閉:這可以通過調用`$client->connect()`和輕松實現`$client->disconnect()`。請注意,這些方法對聚合連接的影響可能因每個具體實現而異。
### [](http://packagist.p2hp.com/packages/predis/predis#user-content-client-configuration)客戶端配置
可以通過將特定的客戶端選項傳遞給 的第二個參數來配置客戶端的許多方面和行為`Predis\Client::__construct()`:
~~~
$ client = new Predis \ Client ( $ parameters , [ 'prefix' => 'sample:' ]);
~~~
選項使用類似 DI 的迷你容器進行管理,并且它們的值僅在需要時才可以延遲初始化。Predis 默認支持的客戶端選項有:
* `prefix`: 前綴字符串應用于命令中找到的每個鍵。
* `exceptions`:客戶端是否應該在 Redis 錯誤時拋出或返回響應。
* `connections`:連接后端或連接工廠實例的列表。
* `cluster`: 指定集群后端(`predis`或`redis`可調用)。
* `replication`: 指定復制后端(`predis`或`sentinel`可調用)。
* `aggregate`:使用自定義聚合連接(可調用)配置客戶端。
* `parameters`:聚合連接的默認連接參數列表。
* `commands`:指定要通過庫使用的命令工廠實例。
用戶還可以為自定義選項提供存儲在選項容器中的值或可調用對象(用于延遲初始化),以供以后通過庫使用。
### [](http://packagist.p2hp.com/packages/predis/predis#user-content-aggregate-connections)聚合連接
聚合連接是 Predis 實現集群和復制的基礎,它們用于將多個連接分組到單個 Redis 節點,并根據上下文隱藏正確處理它們所需的特定邏輯。在創建新的客戶端實例時,聚合連接通常需要一系列連接參數以及適當的客戶端選項。
#### [](http://packagist.p2hp.com/packages/predis/predis#user-content-cluster)簇
Predis 可以配置為使用傳統的客戶端分片方法以集群模式工作,以創建獨立節點的集群并在它們之間分配密鑰空間。這種方法需要對節點進行某種外部健康監控,并且需要在添加或刪除節點時手動重新平衡鍵空間:
~~~
$參數= [ 'tcp://10.0.0.1' , 'tcp://10.0.0.2' , 'tcp://10.0.0.3' ];
$選項 = [ '集群' => 'predis' ];
$ client = new Predis \ Client ( $ parameters );
~~~
與 Redis 3.0 一起,以[redis-cluster](http://redis.io/topics/cluster-tutorial)的形式引入了一種新的有監督和協調的集群類型。這種方法使用不同的算法來分配密鑰空間,Redis 節點通過 gossip 協議進行通信來協調自己,以處理健康狀態、重新平衡、節點發現和請求重定向。為了連接到由 redis-cluster 管理的集群,客戶端需要一個節點列表(不一定完整,因為它會在必要時自動發現新節點)并且`cluster`客戶端選項設置為`redis`:
~~~
$參數= [ 'tcp://10.0.0.1' , 'tcp://10.0.0.2' , 'tcp://10.0.0.3' ];
$選項 = [ '集群' => 'redis' ];
$ client = new Predis \ Client ( $ parameters , $ options );
~~~
#### [](http://packagist.p2hp.com/packages/predis/predis#user-content-replication)復制
客戶端可以配置為在單個主/多個從設置中運行,以提供更好的服務可用性。使用復制時,Predis 識別只讀命令并將它們發送到隨機從屬,以提供某種負載平衡,并在檢測到執行任何最終會修改的操作的命令時切換到主控鍵空間或鍵的值。當從站失敗時,客戶端不會引發連接錯誤,而是嘗試回退到配置中提供的從站中的不同從站。
在復制模式下使用客戶端所需的基本配置需要將一臺 Redis 服務器標識為主服務器(這可以通過將參數設置為 來通過連接參數完成`role`)`master`和一個或多個從服務器(在這種情況下,設置`role`為`slave`從屬服務器是可選的):
~~~
$參數= [ 'tcp://10.0.0.1?role=master' , 'tcp://10.0.0.2' , 'tcp://10.0.0.3' ];
$選項 = [ '復制' => 'predis' ];
$ client = new Predis \ Client ( $ parameters , $ options );
~~~
上面的配置有一個靜態的服務器列表,完全依賴于客戶端的邏輯,但是可以依賴于[`redis-sentinel`](http://redis.io/topics/sentinel)一個更健壯的 HA 環境,其中哨兵??服務器充當客戶端進行服務發現的權限來源。客戶端使用 redis-sentinel 所需的最低配置是指向一堆哨兵實例的連接參數列表,`replication`選項設置為`sentinel`,`service`選項設置為服務名稱:
~~~
$ sentinels = [ 'tcp://10.0.0.1' , 'tcp://10.0.0.2' , 'tcp://10.0.0.3' ];
$ options = [ 'replication' => 'sentinel' , 'service' => 'mymaster' ];
$ client = new Predis \ Client ( $ sentinels , $ options );
~~~
如果主節點和從節點配置為要求客戶端進行身份驗證,則必須通過全局`parameters`客戶端選項提供密碼。此選項還可用于指定不同的數據庫索引。客戶端選項數組將如下所示:
~~~
$ options = [
'replication' => 'sentinel' ,
'service' => 'mymaster' ,
'parameters' => [
'password' => $ secretpassword ,
'database' => 10 ,
],
];
~~~
雖然 Predis 能夠區分執行寫入和只讀操作的命令,`EVAL`并`EVALSHA`表示客戶端切換到主節點的極端情況,因為它無法判斷 Lua 腳本何時可以安全地在從屬節點上執行。雖然這確實是默認行為,但當某些 Lua 腳本不執行寫操作時,可以提供一個提示來告訴客戶端堅持使用從屬來執行它們:
~~~
$參數= [ 'tcp://10.0.0.1?role=master' , 'tcp://10.0.0.2' , 'tcp://10.0.0.3' ];
$ options = [ 'replication' => function () {
// 設置不會觸發從從節點切換到主節點的腳本。
$策略=新的 Predis \復制\復制策略();
$策略-> setScriptReadOnly ( $ LUA_SCRIPT );
返回 新的 Predis \ Connection \ Replication \ MasterSlaveReplication($策略);
}];
$ client = new Predis \ Client ( $ parameters , $ options );
$客戶端->評估( $ LUA_SCRIPT, 0); // 使用 `eval` 連接到 slave...
$ client -> evalsha ( sha1 ( $ LUA_SCRIPT ), 0 ); // ... 還有 `evalsha`。
~~~
該[`examples`](https://github.com/predis/predis/blob/HEAD/examples/)目錄包含一些腳本,這些腳本演示了如何配置客戶端并將其用于在基本和復雜場景中利用復制。
### [](http://packagist.p2hp.com/packages/predis/predis#user-content-command-pipelines)命令管道
當需要將許多命令發送到服務器時,流水線可以通過減少網絡往返時間引入的延遲來幫助提高性能。流水線也適用于聚合連接。由于其流暢的接口,客戶端可以在可調用塊內執行管道或返回具有鏈接命令能力的管道實例:
~~~
// 在給定的可調用塊內執行管道:
$ response = $ client -> pipeline ( function ( $ pipe ) {
for ( $ i = 0 ; $ i < 1000 ; $ i ++) {
$ pipe -> set ( "key:$i" , str_pad ( $ i , 4 , '0' , 0 ));
$管道->獲取( "key:$i" );
}
});
// 由于其流暢的接口,返回一個可以鏈接的管道:
$ responses = $ client -> pipeline ()-> set ( 'foo' , 'bar' )-> get ( 'foo' )-> execute () ;
~~~
### [](http://packagist.p2hp.com/packages/predis/predis#user-content-transactions)交易
客戶端為 Redis 事務提供了一個抽象,它基于命令管道`MULTI`并`EXEC`具有與命令管道類似的接口:
~~~
// 在給定的可調用塊內執行事務:
$ responses = $ client -> transaction ( function ( $ tx ) {
$ tx -> set ( 'foo' , 'bar' );
$ tx -> get ( 'foo' );
});
// 由于其流暢的接口,返回一個可以鏈接的事務:
$ response = $ client -> transaction ()-> set ( 'foo' , 'bar' )-> get ( 'foo' )-> execute () ;
~~~
這種抽象可以執行檢查和設置操作,`WATCH`并在ed 鍵被觸摸`UNWATCH`時提供由 Redis 中止的事務的自動重試。`WATCH`對于使用 CAS 的事務示例,您可以查看[以下示例](https://github.com/predis/predis/blob/HEAD/examples/transaction_using_cas.php)。
### [](http://packagist.p2hp.com/packages/predis/predis#user-content-adding-new-commands)添加新命令
雖然我們嘗試更新 Predis 以與 Redis 中可用的所有命令保持同步,但您可能更愿意堅持使用舊版本的庫或提供不同的方式來過濾參數或解析特定命令的響應。為了實現這一點,Predis 提供了實現新命令類的能力,以在客戶端使用的默認命令工廠中定義或覆蓋命令:
~~~
// 通過擴展 Predis\Command\Command 定義一個新命令:
class BrandNewRedisCommand extends Predis \ Command \ Command
{
公共 函數 getId ()
{
返回 'NEWCMD' ;
}
}
// 在當前命令工廠中注入你的命令:
$ client = new Predis \ Client ( $ parameters , [
'commands' => [
'newcmd' => 'BrandNewRedisCommand' ,
],
]);
$響應= $客戶端-> newcmd ();
~~~
還有一種方法可以在不過濾參數或解析響應的情況下發送原始命令。[用戶必須按照Redis 文檔中為 commands](http://redis.io/commands)定義的簽名,將命令的參數列表作為數組提供:
~~~
$ response = $ client -> executeRaw ([ 'SET' , 'foo' , 'bar' ]);
~~~
### [](http://packagist.p2hp.com/packages/predis/predis#user-content-script-commands)腳本命令
雖然可以直接使用and在 Redis 2.6+ 上利用[Lua 腳本](http://redis.io/commands/eval),但 Predis 提供腳本命令作為構建在它們之上的更高級別的抽象,以使事情變得簡單。腳本命令可以在客戶端使用的命令工廠中注冊,并且可以像普通 Redis 命令一樣訪問,但它們定義了傳輸到服務器以進行遠程執行的 Lua 腳本。在內部,它們默認使用并通過其 SHA1 哈希標識腳本以節省帶寬,但在需要時用作備用:[`EVAL`](http://redis.io/commands/eval)[`EVALSHA`](http://redis.io/commands/evalsha)[`EVALSHA`](http://redis.io/commands/evalsha)[`EVAL`](http://redis.io/commands/eval)
~~~
// 通過擴展 Predis\Command\ScriptCommand 定義一個新的腳本命令:
class ListPushRandomValue extends Predis \ Command \ ScriptCommand
{
公共 函數 getKeysCount ()
{
返回 1 ;
}
公共 函數 getScript ()
{
return <<<LUA
math.randomseed(ARGV[1])
local rnd = tostring(math.random())
redis.call('lpush', KEYS[1], rnd)
return rnd
LUA ;
}
}
// 在當前命令工廠注入腳本命令:
$ client = new Predis \ Client ( $ parameters , [
'commands' => [
'lpushrand' => 'ListPushRandomValue' ,
],
]);
$ response = $ client -> lpushrand ( 'random_values' , $ seed = mt_rand ());
~~~
### [](http://packagist.p2hp.com/packages/predis/predis#user-content-customizable-connection-backends)可定制的連接后端
Predis 可以使用不同的連接后端連接到 Redis。其中兩個利用了第三方擴展,例如[phpiredis](https://github.com/nrk/phpiredis),從而獲得了顯著的性能提升,尤其是在處理大型多批量響應時。一種基于 PHP 流,另一種基于`ext-socket`.兩者都支持 TCP/IP 和 UNIX 域套接字:
~~~
$ client = new Predis \ Client ( 'tcp://127.0.0.1' , [
'connections' => [
'tcp' => 'Predis\Connection\PhpiredisStreamConnection' , // PHP 流資源
'unix' => 'Predis \Connection\PhpiredisSocketConnection' , // ext-socket 資源
],
]);
~~~
通過為客戶端選項指定描述性字符串,客戶端也可以配置為依賴于[ppiredis](https://github.com/nrk/phpiredis)`connections`\-backend 。支持的字符串值是:
* `phpiredis-stream`地圖`tcp`,`redis`以及`unix`\_`Predis\Connection\PhpiredisStreamConnection`
* `phpiredis-socket`地圖`tcp`,`redis`以及`unix`\_`Predis\Connection\PhpiredisSocketConnection`
* `phpiredis`只是一個別名`phpiredis-stream`
~~~
$ client = new Predis \ Client ( 'tcp://127.0.0.1' , [ 'connections' => 'phpiredis' ]);
~~~
開發人員可以創建自己的連接類來支持全新的網絡后端、擴展現有類或提供完全不同的實現。連接類必須實現`Predis\Connection\NodeConnectionInterface`或擴展`Predis\Connection\AbstractConnection`:
~~~
MyConnectionClass 類實現 Predis \ Connection \ NodeConnectionInterface
{
// 實現在這里...
}
// 使用 MyConnectionClass 處理 `tcp` 方案的連接:
$ client = new Predis \ Client ( 'tcp://127.0.0.1' , [
'connections' => [ 'tcp' => 'MyConnectionClass' ],
]);
~~~
要更深入地了解如何創建新的連接后端,您可以參考`Predis\Connection`命名空間中可用的標準連接類的實際實現。
## [](http://packagist.p2hp.com/packages/predis/predis#user-content-development)發展
### [](http://packagist.p2hp.com/packages/predis/predis#user-content-reporting-bugs-and-contributing-code)報告錯誤和貢獻代碼
對 Predis 的貢獻受到高度贊賞,無論是以對新功能、錯誤修復或錯誤報告的拉取請求的形式。我們只要求您在提交更改或在問題跟蹤器上提交錯誤之前遵守一[組基本規則](https://github.com/predis/predis/blob/HEAD/CONTRIBUTING.md),以使每個人在項目工作時更容易保持一致。
### [](http://packagist.p2hp.com/packages/predis/predis#user-content-test-suite)測試套件
**注意**:永遠不要針對在生產環境中運行或包含您感興趣的數據的 Redis 實例運行 Predis 附帶的測試套件!
Predis 有一個全面的測試套件,涵蓋了庫的各個方面,并且可以選擇對正在運行的 Redis 實例執行集成測試(需要 >= 2.4.0 以驗證每個命令實現的正確行為。不支持的集成測試Redis 命令會自動跳過。如果您沒有啟動并運行 Redis,則可以禁用集成測試。有關測試此庫的更多詳細信息,請參閱[測試自述文件。](https://github.com/predis/predis/blob/HEAD/tests/README.md)
Predis 使用 GitHub Actions 進行持續集成,過去和當前構建的歷史可以[在其操作頁面上](https://github.com/predis/predis/actions)找到。
- 章節導航
- String命令操作
- string字符類型應用場景
- set get
- incr 自增 decr 自減
- substr字符串截取
- expire 過期時間
- 列出所有的鍵
- del刪除鍵值
- 獲取類型
- rename改鍵名
- 查看存儲鍵與刪除所有鍵
- Redis 16個數據庫操作
- 隨機獲取一個鍵
- list(列表)命令操作應用場景
- set(無序集合)命令操作(SADD無序集合 )
- sort set(有序集合) 排序集合(基數數字排序 )
- hash哈希排序類型使用
- redis訂閱功能(推送功能)
- redis事務功能
- redis設置密碼
- redis持久化aof與rdb及備份恢復的使用
- php操作redis string
- php操作redis set sort set hash list
- thinkphp5使用redis
- thinkphp5.0配置redis中 composer使用說明翻譯文件
- reids過期時間設置
- Redis 序列化 排序 遷移數據庫操作
- 主機從機設置
- 公網訪問方法