Bitte lesen Sie die Einführung zu SmartWiki: http://www.cnblogs.com/lifeil/p/6113323.html
Da die SmartWiki-Demo-Site auf Alibaba Cloud bereitgestellt wird, verfügt Alibaba Cloud über einen 128 MB kostenlosen Memcache-Dienst. Nach der Konfiguration gemäß der Memcached-Konfigurationsmethode habe ich festgestellt, dass Laravel einen Fehler gemeldet hat addServer hat einen Fehler und kann nicht mit dem Memcache von Alibaba Cloud verbunden werden.
Ich war hilflos, also habe ich ein Skript im Alibaba Cloud-Installationshandbuch geschrieben und es auf den Server gestellt. Dadurch konnte ich eine Verbindung herstellen und schreiben.
Das von Alibaba Cloud bereitgestellte Skript lautet wie folgt:
<?<span style="color: #000000">php </span><span style="color: #800080">$connect</span> = <span style="color: #0000ff">new</span> Memcached; <span style="color: #008000">//</span><span style="color: #008000">声明一个新的memcached链接</span> <span style="color: #800080">$connect</span>->setOption(Memcached::OPT_COMPRESSION, <span style="color: #0000ff">false</span>); <span style="color: #008000">//</span><span style="color: #008000">关闭压缩功能</span> <span style="color: #800080">$connect</span>->setOption(Memcached::OPT_BINARY_PROTOCOL, <span style="color: #0000ff">true</span>); <span style="color: #008000">//</span><span style="color: #008000">使用binary二进制协议</span> <span style="color: #800080">$connect</span>->addServer('00000000.ocs.aliyuncs.com', 11211); <span style="color: #008000">//</span><span style="color: #008000">添加OCS实例地址及端口号 //$connect->setSaslAuthData('aaaaaaaaaa, 'password'); //设置OCS帐号密码进行鉴权,如已开启免密码功能,则无需此步骤</span> <span style="color: #800080">$connect</span>->set("hello", "world"<span style="color: #000000">); </span><span style="color: #0000ff">echo</span> 'hello: ',<span style="color: #800080">$connect</span>->get("hello"<span style="color: #000000">); </span><span style="color: #008080">print_r</span>( <span style="color: #800080">$connect</span>-><span style="color: #000000">getVersion()); </span><span style="color: #800080">$connect</span>->quit();
Wenn man sich den Memcached-Treiber von Laravel ansieht, sieht der Code zum Erstellen eines Memcached-Objekts in /vendor/laravel/framework/src/Illuminate/Cache/MemcachedConnector.php wie folgt aus:
<span style="color: #0000ff">public</span> <span style="color: #0000ff">function</span> connect(<span style="color: #0000ff">array</span> <span style="color: #800080">$servers</span><span style="color: #000000">) { </span><span style="color: #800080">$memcached</span> = <span style="color: #800080">$this</span>-><span style="color: #000000">getMemcached(); </span><span style="color: #008000">//</span><span style="color: #008000"> For each server in the array, we'll just extract the configuration and add // the server to the Memcached connection. Once we have added all of these // servers we'll verify the connection is successful and return it back.</span> <span style="color: #0000ff">foreach</span> (<span style="color: #800080">$servers</span> <span style="color: #0000ff">as</span> <span style="color: #800080">$server</span><span style="color: #000000">) { </span><span style="color: #800080">$memcached</span>-><span style="color: #000000">addServer( </span><span style="color: #800080">$server</span>['host'], <span style="color: #800080">$server</span>['port'], <span style="color: #800080">$server</span>['weight'<span style="color: #000000">] ); } </span><span style="color: #800080">$memcachedStatus</span> = <span style="color: #800080">$memcached</span>-><span style="color: #000000">getVersion(); </span><span style="color: #0000ff">if</span> (! <span style="color: #008080">is_array</span>(<span style="color: #800080">$memcachedStatus</span><span style="color: #000000">)) { </span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> RuntimeException('No Memcached servers added.'<span style="color: #000000">); } </span><span style="color: #0000ff">if</span> (<span style="color: #008080">in_array</span>('255.255.255', <span style="color: #800080">$memcachedStatus</span>) && <span style="color: #008080">count</span>(<span style="color: #008080">array_unique</span>(<span style="color: #800080">$memcachedStatus</span>)) === 1<span style="color: #000000">) { </span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> RuntimeException('Could not establish Memcached connection.'<span style="color: #000000">); } </span><span style="color: #0000ff">return</span> <span style="color: #800080">$memcached</span><span style="color: #000000">; }</span>
Sie können sehen, dass Memcached von Laravel die Option der setOption-Methode nicht festlegt. Es umfasst nur den einfachsten Verbindungsaufbau und ruft dann getVersion auf, um zu testen, ob eine Verbindung besteht. Der Democode von Alibaba Cloud legt die Optionen zum Deaktivieren der Komprimierung und zur Verwendung des binären Binärprotokolls fest.
Es bleibt keine andere Wahl, als die Funktionen von Memcached selbst zu erweitern, um benutzerdefinierte Optionen zu implementieren. Der erweiterte Cache in Laravel kann mit Cache::extend erweitert werden. Der Erweiterungscode lautet wie folgt:
Cache::extend('MemcachedExtend', <span style="color: #0000ff">function</span> (<span style="color: #800080">$app</span><span style="color: #000000">) { </span><span style="color: #800080">$memcached</span> = <span style="color: #800080">$this</span>->createMemcached(<span style="color: #800080">$app</span><span style="color: #000000">); </span><span style="color: #008000">//</span><span style="color: #008000"> 从配置文件中读取缓存前缀</span> <span style="color: #800080">$prefix</span> = <span style="color: #800080">$app</span>['config']['cache.prefix'<span style="color: #000000">]; </span><span style="color: #008000">//</span><span style="color: #008000"> 创建 MemcachedStore 对象</span> <span style="color: #800080">$store</span> = <span style="color: #0000ff">new</span> MemcachedStore(<span style="color: #800080">$memcached</span>, <span style="color: #800080">$prefix</span><span style="color: #000000">); </span><span style="color: #008000">//</span><span style="color: #008000"> 创建 Repository 对象,并返回</span> <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> Repository(<span style="color: #800080">$store</span><span style="color: #000000">); });</span>
<span style="color: #008000">/*</span><span style="color: #008000">* * 创建Memcached对象 * @param $app * @return mixed </span><span style="color: #008000">*/</span> <span style="color: #0000ff">protected</span> <span style="color: #0000ff">function</span> createMemcached(<span style="color: #800080">$app</span><span style="color: #000000">) { </span><span style="color: #008000">//</span><span style="color: #008000"> 从配置文件中读取 Memcached 服务器配置</span> <span style="color: #800080">$servers</span> = <span style="color: #800080">$app</span>['config']['cache.stores.MemcachedExtend.servers'<span style="color: #000000">]; </span><span style="color: #008000">//</span><span style="color: #008000"> 利用 Illuminate\Cache\MemcachedConnector 类来创建新的 Memcached 对象</span> <span style="color: #800080">$memcached</span> = <span style="color: #0000ff">new</span><span style="color: #000000"> \Memcached; </span><span style="color: #0000ff">foreach</span> (<span style="color: #800080">$servers</span> <span style="color: #0000ff">as</span> <span style="color: #800080">$server</span><span style="color: #000000">) { </span><span style="color: #800080">$memcached</span>-><span style="color: #000000">addServer( </span><span style="color: #800080">$server</span>['host'], <span style="color: #800080">$server</span>['port'], <span style="color: #800080">$server</span>['weight'<span style="color: #000000">] ); } </span><span style="color: #008000">//</span><span style="color: #008000"> 如果服务器上的 PHP Memcached 扩展支持 SASL 认证</span> <span style="color: #0000ff">if</span> (<span style="color: #008080">ini_get</span>('memcached.use_sasl') && <span style="color: #0000ff">isset</span>(<span style="color: #800080">$app</span>['config']['cache.storess.MemcachedExtend.memcached_user']) && <span style="color: #0000ff">isset</span>(<span style="color: #800080">$app</span>['config']['cache.storess.MemcachedExtend.memcached_pass'<span style="color: #000000">])) { </span><span style="color: #008000">//</span><span style="color: #008000"> 从配置文件中读取 sasl 认证用户名</span> <span style="color: #800080">$user</span> = <span style="color: #800080">$app</span>['config']['cache.storess.MemcachedExtend.memcached_user'<span style="color: #000000">]; </span><span style="color: #008000">//</span><span style="color: #008000"> 从配置文件中读取 sasl 认证密码</span> <span style="color: #800080">$pass</span> = <span style="color: #800080">$app</span>['config']['cache.storess.MemcachedExtend.memcached_pass'<span style="color: #000000">]; </span><span style="color: #008000">//</span><span style="color: #008000"> 指定用于 sasl 认证的账号密码</span> <span style="color: #800080">$memcached</span>->setSaslAuthData(<span style="color: #800080">$user</span>, <span style="color: #800080">$pass</span><span style="color: #000000">); } </span><span style="color: #008000">//</span><span style="color: #008000">扩展</span> <span style="color: #0000ff">if</span> (<span style="color: #0000ff">isset</span>(<span style="color: #800080">$app</span>['config']['cache.stores.MemcachedExtend.options'<span style="color: #000000">])) { </span><span style="color: #0000ff">foreach</span> (<span style="color: #800080">$app</span>['config']['cache.stores.MemcachedExtend.options'] <span style="color: #0000ff">as</span> <span style="color: #800080">$key</span> => <span style="color: #800080">$option</span><span style="color: #000000">) { </span><span style="color: #800080">$memcached</span>->setOption(<span style="color: #800080">$key</span>, <span style="color: #800080">$option</span><span style="color: #000000">); } } </span><span style="color: #800080">$memcachedStatus</span> = <span style="color: #800080">$memcached</span>-><span style="color: #000000">getVersion(); </span><span style="color: #0000ff">if</span> (! <span style="color: #008080">is_array</span>(<span style="color: #800080">$memcachedStatus</span><span style="color: #000000">)) { </span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> RuntimeException('No Memcached servers added.'<span style="color: #000000">); } </span><span style="color: #0000ff">if</span> (<span style="color: #008080">in_array</span>('255.255.255', <span style="color: #800080">$memcachedStatus</span>) && <span style="color: #008080">count</span>(<span style="color: #008080">array_unique</span>(<span style="color: #800080">$memcachedStatus</span>)) === 1<span style="color: #000000">) { </span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> RuntimeException('Could not establish Memcached connection.'<span style="color: #000000">); } </span><span style="color: #0000ff">return</span> <span style="color: #800080">$memcached</span><span style="color: #000000">; }</span>
Im Internet kursieren Artikel über die Laravel-Cache-Erweiterung, bei denen das Lesen der Konfiguration in den Versionen 5.2 und höher nicht möglich ist.
Für den Cache-Erweiterungscode muss ein ServiceProvider erstellt werden, um den Service Provider zu registrieren. Der Dienstanbieter ist das Zentrum für den Start der Laravel-Anwendung. Ihre eigene Anwendung und alle Kerndienste von Laravel werden über den Dienstanbieter gestartet.
Aber was meinen wir mit „Start“? In der Regel bedeutet dies, Dinge zu registrieren, einschließlich der Registrierung von Service-Container-Bindungen, Ereignis-Listenern, Middleware und sogar Routen. Dienstanbieter sind das Zentrum der Anwendungskonfiguration.
Wenn Sie die mit Laravel gelieferte Datei config/app.php öffnen, sehen Sie ein Provider-Array. Hier sind alle von der Anwendung zu ladenden Dienstanbieterklassen aufgeführt bedeutet, dass sie nicht geladen werden. Sie werden bei jeder Anfrage geladen und nur dann, wenn sie tatsächlich benötigt werden.
Alle Dienstanbieter erben von der IlluminateSupportServiceProvider-Klasse. Die meisten Dienstanbieter bieten zwei Methoden: Registrieren und Booten. Bei der Register-Methode müssen Sie das Ding lediglich an den Service-Container binden. Versuchen Sie nicht, Ereignis-Listener, Routen oder andere Funktionen darin zu registrieren.
Sie können einfach einen neuen Anbieter über den Artisan-Befehl make:provider:
generierenphp artisan <span style="color: #0000ff">make</span>:provider MemcachedExtendServiceProvider
Alle Dienstanbieter werden über die Konfigurationsdatei config/app.php registriert. Diese Datei enthält ein Anbieterarray, das die Namen aller Dienstanbieter auflistet. Diese Dienstanbieter starten Laravel Kernkomponenten wie Mail, Warteschlangen, Cache usw.
Um Ihren eigenen Dienstanbieter zu registrieren, hängen Sie ihn einfach an dieses Array an:
<span style="color: #800000">'</span><span style="color: #800000">providers</span><span style="color: #800000">'</span> =><span style="color: #000000"> [ SmartWiki\Providers\MemcachedExtendServiceProvider::class </span><span style="color: #008000">//</span><span style="color: #008000">在providers节点添加实现的provider</span> ]
Konfigurieren Sie auch die Memcached-Konfiguration in config/cache.php:
'MemcachedExtend' =><span style="color: #000000"> [ </span>'driver' => 'MemcachedExtend', 'servers' =><span style="color: #000000"> [ [ </span>'host' => env('MEMCACHED_EXTEND_HOST', '127.0.0.1'), 'port' => env('MEMCACHED_EXTEND_PORT', 11211), 'weight' => 100,<span style="color: #000000"> ]</span>,<span style="color: #000000"> ]</span>, 'options' =><span style="color: #000000"> [ \Memcached</span>::OPT_BINARY_PROTOCOL => <span style="color: #0000ff">true</span>,<span style="color: #000000"> \Memcached</span>::OPT_COMPRESSION => <span style="color: #0000ff">false</span><span style="color: #000000"> ] ]</span>
Wenn Sie die Sitzung in unserem erweiterten Cache speichern müssen, müssen Sie auch Session::extend aufrufen, um unseren Sitzungsspeicher zu erweitern:
Session::extend('MemcachedExtend',<span style="color: #0000ff">function</span> (<span style="color: #800080">$app</span><span style="color: #000000">){ </span><span style="color: #800080">$memcached</span> = <span style="color: #800080">$this</span>->createMemcached(<span style="color: #800080">$app</span><span style="color: #000000">); </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> MemcachedSessionHandler(<span style="color: #800080">$memcached</span><span style="color: #000000">); });</span>
Danach können wir unseren erweiterten Cache in .env konfigurieren. Der vollständige Code lautet wie folgt:
<?<span style="color: #000000">php namespace SmartWiki\Providers; </span><span style="color: #0000ff">use</span><span style="color: #000000"> Illuminate\Cache\Repository; </span><span style="color: #0000ff">use</span><span style="color: #000000"> Illuminate\Cache\MemcachedStore; </span><span style="color: #0000ff">use</span><span style="color: #000000"> Illuminate\Support\ServiceProvider; </span><span style="color: #0000ff">use</span><span style="color: #000000"> Cache; </span><span style="color: #0000ff">use</span><span style="color: #000000"> Session; </span><span style="color: #0000ff">use</span><span style="color: #000000"> Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcachedSessionHandler; </span><span style="color: #0000ff">use</span><span style="color: #000000"> RuntimeException; </span><span style="color: #0000ff">class</span> MemcachedExtendServiceProvider <span style="color: #0000ff">extends</span><span style="color: #000000"> ServiceProvider { </span><span style="color: #008000">/*</span><span style="color: #008000">* * Bootstrap the application services. * * @return void </span><span style="color: #008000">*/</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">function</span><span style="color: #000000"> boot() { Cache</span>::extend('MemcachedExtend', <span style="color: #0000ff">function</span> (<span style="color: #800080">$app</span><span style="color: #000000">) { </span><span style="color: #800080">$memcached</span> = <span style="color: #800080">$this</span>->createMemcached(<span style="color: #800080">$app</span><span style="color: #000000">); </span><span style="color: #008000">//</span><span style="color: #008000"> 从配置文件中读取缓存前缀</span> <span style="color: #800080">$prefix</span> = <span style="color: #800080">$app</span>['config']['cache.prefix'<span style="color: #000000">]; </span><span style="color: #008000">//</span><span style="color: #008000"> 创建 MemcachedStore 对象</span> <span style="color: #800080">$store</span> = <span style="color: #0000ff">new</span> MemcachedStore(<span style="color: #800080">$memcached</span>, <span style="color: #800080">$prefix</span><span style="color: #000000">); </span><span style="color: #008000">//</span><span style="color: #008000"> 创建 Repository 对象,并返回</span> <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> Repository(<span style="color: #800080">$store</span><span style="color: #000000">); }); Session</span>::extend('MemcachedExtend',<span style="color: #0000ff">function</span> (<span style="color: #800080">$app</span><span style="color: #000000">){ </span><span style="color: #800080">$memcached</span> = <span style="color: #800080">$this</span>->createMemcached(<span style="color: #800080">$app</span><span style="color: #000000">); </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> MemcachedSessionHandler(<span style="color: #800080">$memcached</span><span style="color: #000000">); }); } </span><span style="color: #008000">/*</span><span style="color: #008000">* * Register the application services. * * @return void </span><span style="color: #008000">*/</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">function</span><span style="color: #000000"> register() { </span><span style="color: #008000">// </span><span style="color: #000000"> } </span><span style="color: #008000">/*</span><span style="color: #008000">* * 创建Memcached对象 * @param $app * @return mixed </span><span style="color: #008000">*/</span> <span style="color: #0000ff">protected</span> <span style="color: #0000ff">function</span> createMemcached(<span style="color: #800080">$app</span><span style="color: #000000">) { </span><span style="color: #008000">//</span><span style="color: #008000"> 从配置文件中读取 Memcached 服务器配置</span> <span style="color: #800080">$servers</span> = <span style="color: #800080">$app</span>['config']['cache.stores.MemcachedExtend.servers'<span style="color: #000000">]; </span><span style="color: #008000">//</span><span style="color: #008000"> 利用 Illuminate\Cache\MemcachedConnector 类来创建新的 Memcached 对象</span> <span style="color: #800080">$memcached</span> = <span style="color: #0000ff">new</span><span style="color: #000000"> \Memcached; </span><span style="color: #0000ff">foreach</span> (<span style="color: #800080">$servers</span> <span style="color: #0000ff">as</span> <span style="color: #800080">$server</span><span style="color: #000000">) { </span><span style="color: #800080">$memcached</span>-><span style="color: #000000">addServer( </span><span style="color: #800080">$server</span>['host'], <span style="color: #800080">$server</span>['port'], <span style="color: #800080">$server</span>['weight'<span style="color: #000000">] ); } </span><span style="color: #008000">//</span><span style="color: #008000"> 如果服务器上的 PHP Memcached 扩展支持 SASL 认证</span> <span style="color: #0000ff">if</span> (<span style="color: #008080">ini_get</span>('memcached.use_sasl') && <span style="color: #0000ff">isset</span>(<span style="color: #800080">$app</span>['config']['cache.storess.MemcachedExtend.memcached_user']) && <span style="color: #0000ff">isset</span>(<span style="color: #800080">$app</span>['config']['cache.storess.MemcachedExtend.memcached_pass'<span style="color: #000000">])) { </span><span style="color: #008000">//</span><span style="color: #008000"> 从配置文件中读取 sasl 认证用户名</span> <span style="color: #800080">$user</span> = <span style="color: #800080">$app</span>['config']['cache.storess.MemcachedExtend.memcached_user'<span style="color: #000000">]; </span><span style="color: #008000">//</span><span style="color: #008000"> 从配置文件中读取 sasl 认证密码</span> <span style="color: #800080">$pass</span> = <span style="color: #800080">$app</span>['config']['cache.storess.MemcachedExtend.memcached_pass'<span style="color: #000000">]; </span><span style="color: #008000">//</span><span style="color: #008000"> 指定用于 sasl 认证的账号密码</span> <span style="color: #800080">$memcached</span>->setSaslAuthData(<span style="color: #800080">$user</span>, <span style="color: #800080">$pass</span><span style="color: #000000">); } </span><span style="color: #008000">//</span><span style="color: #008000">扩展</span> <span style="color: #0000ff">if</span> (<span style="color: #0000ff">isset</span>(<span style="color: #800080">$app</span>['config']['cache.stores.MemcachedExtend.options'<span style="color: #000000">])) { </span><span style="color: #0000ff">foreach</span> (<span style="color: #800080">$app</span>['config']['cache.stores.MemcachedExtend.options'] <span style="color: #0000ff">as</span> <span style="color: #800080">$key</span> => <span style="color: #800080">$option</span><span style="color: #000000">) { </span><span style="color: #800080">$memcached</span>->setOption(<span style="color: #800080">$key</span>, <span style="color: #800080">$option</span><span style="color: #000000">); } } </span><span style="color: #800080">$memcachedStatus</span> = <span style="color: #800080">$memcached</span>-><span style="color: #000000">getVersion(); </span><span style="color: #0000ff">if</span> (! <span style="color: #008080">is_array</span>(<span style="color: #800080">$memcachedStatus</span><span style="color: #000000">)) { </span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> RuntimeException('No Memcached servers added.'<span style="color: #000000">); } </span><span style="color: #0000ff">if</span> (<span style="color: #008080">in_array</span>('255.255.255', <span style="color: #800080">$memcachedStatus</span>) && <span style="color: #008080">count</span>(<span style="color: #008080">array_unique</span>(<span style="color: #800080">$memcachedStatus</span>)) === 1<span style="color: #000000">) { </span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> RuntimeException('Could not establish Memcached connection.'<span style="color: #000000">); } </span><span style="color: #0000ff">return</span> <span style="color: #800080">$memcached</span><span style="color: #000000">; } }</span>
Offizielle SmartWiki-Website: https://www.iminho.me
SmartWiki-Quellcode: https://github.com/lifei6671/SmartWiki