>  기사  >  php教程  >  SmartWiki 개발 일기 Laravel 캐시 확장

SmartWiki 개발 일기 Laravel 캐시 확장

WBOY
WBOY원래의
2016-12-05 13:26:251606검색

SmartWiki 소개를 읽어보세요: http://www.cnblogs.com/lifeil/p/6113323.html

SmartWiki 데모 사이트는 Alibaba Cloud에 배포되기 때문에 Alibaba Cloud에는 128M의 무료 Memcache 서비스가 있습니다. Memcached 구성 방법에 따라 구성한 후 Laravel에서 오류를 보고한 것을 확인했는데 오류 위치는 다음과 같습니다. addServer에 오류가 있어 Alibaba Cloud의 Memcache에 연결할 수 없습니다.

무기력해서 알리바바 클라우드 설치 매뉴얼에 스크립트를 작성해서 서버에 올려두니 접속해서 쓸 수 있었어요.

Alibaba Cloud에서 제공하는 스크립트는 다음과 같습니다.

<?<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();

laravel의 Memcached 드라이버를 살펴보면 /vendor/laravel/framework/src/Illuminate/Cache/MemcachedConnector.php에 Memcached 객체를 생성하는 코드는 다음과 같습니다.

<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>

Laravel의 Memcached에서는 가장 간단한 연결 설정만 포함하고 getVersion을 호출하여 setOption 메소드의 옵션을 설정하지 않는 것을 볼 수 있습니다. Alibaba Cloud의 데모 코드는 압축을 끄고 바이너리 바이너리 프로토콜을 사용하는 옵션을 설정합니다.

사용자 지정 옵션을 구현하려면 Memcached의 기능을 직접 확장하는 수밖에 없습니다. laravel의 확장 캐시는 Cache::extend를 사용하여 확장할 수 있습니다. 확장코드는 다음과 같습니다.

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>

라라벨 캐시 확장에 관한 기사가 인터넷에 떠도는데, 버전 5.2 이상에서는 구성 읽기가 적용되지 않습니다.

캐시 확장 코드에서는 서비스 제공자를 등록하기 위해 ServiceProvider를 생성해야 합니다. 서비스 제공자는 라라벨 애플리케이션 시작의 중심입니다. 자신의 애플리케이션과 라라벨의 모든 핵심 서비스는 서비스 제공자를 통해 시작됩니다.

그런데 '출시'란 무엇을 의미하나요? 일반적으로 이는 서비스 컨테이너 바인딩, 이벤트 리스너, 미들웨어 및 경로 등록을 포함하여 항목을 등록하는 것을 의미합니다. 서비스 제공자는 애플리케이션 구성의 중심입니다.

Laravel과 함께 제공되는 config/app.php 파일을 열면 공급자 배열이 표시됩니다. 여기에는 애플리케이션에 의해 로드되는 모든 서비스 공급자 클래스가 있습니다. 물론 이들 중 대부분은 지연 로드됩니다. 모든 요청에 ​​대해 로드되고 실제로 필요할 때만 로드됩니다.

모든 서비스 제공자는 IlluminateSupportServiceProvider 클래스에서 상속됩니다. 대부분의 서비스 제공업체에는 등록 및 부팅이라는 두 가지 방법이 있습니다. 등록 메소드에서 해야 할 일은 서비스 컨테이너에 바인딩하는 것뿐입니다. 이벤트 리스너, 경로 또는 기타 기능을 등록하려고 시도하지 마십시오.

Artisan 명령어 make:provider:

를 통해 간단히 새로운 공급자를 생성할 수 있습니다.
php artisan <span style="color: #0000ff">make</span>:provider MemcachedExtendServiceProvider

모든 서비스 제공자는 구성 파일 config/app.php를 통해 등록됩니다. 이 파일에는 모든 서비스 제공자의 이름을 나열하는 제공자 배열이 포함되어 있습니다. 기본적으로 모든 핵심 서비스 제공자는 Laravel을 시작합니다. 메일, 대기열, 캐시 등과 같은 핵심 구성 요소

귀하의 서비스 제공업체를 등록하려면 다음 배열에 추가하세요.

<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>
]

또한 config/cache.php에서 Memcached 구성을 구성합니다:

'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>

확장 캐시에 세션을 저장해야 하는 경우 Session::extend를 호출하여 세션 저장 공간을 확장해야 합니다.

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>

그런 다음 .env에서 확장 캐시를 구성할 수 있습니다. 전체 코드는 다음과 같습니다.

<?<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>
스마트위키코드

스마트위키 공식 홈페이지: https://www.iminho.me

SmartWiki 소스 코드: https://github.com/lifei6671/SmartWiki

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.