使用 Composer Pusher 库命名空间

Namespacing with Composer Pusher Library

我已经使用 composer 安装了 https://packagist.org/packages/pusher/pusher-php-server 并且 PSR-4 自动加载了我应用程序中的所有包。

我能够使用从未提及 "use namespace" 的页面调用的基本代码成功连接到 Pusher API:

$pusher = new Pusher(
            $app->config->get('pusher.api-key'), 
            $app->config->get('pusher.api-secret'),
            $app->config->get('pusher.app-id'),
            array('encrypted' => true)
        );

我决定我希望所有 Pusher 连接代码都在它自己的 class 中,所以我在它自己的命名空间中创建了下面的 class,并将其保存为 PusherConnect.php Smawt/Helpers 目录:

<?php

namespace Smawt\Helpers;

class PusherConnect
{
    protected $app;

    public function __construct($app)
    {
        $this->app = $app;

        $pusher = new Pusher(
            $this->app->config->get('pusher.api-key'), 
            $this->app->config->get('pusher.api-secret'),
            $this->app->config->get('pusher.app-id'),
            array('encrypted' => true)
        );

        $results = $pusher->get_channels( array( 'filter_by_prefix' => 'user_') );
        $channel_count = count($results->channels);

        $this->app->view->appendData([
            'channels_count' => $channel_count
        ]);

        $pusher->channel_count = $channel_count;

        return $pusher;
    }

    public function check()
    {
        if (!$this->app->config->get('pusher.api-key')) {
            $this->app->flash('global', 'No Pusher account has been set up.');
            return $this->app->response->redirect($this->app->urlFor('home'));
        }
    }
}

然后我用

实例化了对象
<?php

use Smawt\Helpers\PusherConnect;

$pusher = new PusherConnect($app);

但我遇到了

Fatal error: Class 'Smawt\Helpers\Pusher' not found in C:\Users\...\PusherConnect.php on line 13

所以,我意识到 pusher-php-server classes 没有命名空间,因为 Composer 生成的 autoload_psr4.php 文件中没有提到 Pusher 命名空间。因此,我编辑了供应商提供的 Pusher.php 文件:

namespace Pusher;

class PusherException extends \Exception
{
}

class Pusher
{ ...

和我自己的 PusherConnect class

public function __construct($app)
    {
        $this->app = $app;

        $pusher = new \Pusher\Pusher(

一切都开始工作了。

问题似乎与从我自己的 class 中实例化非命名空间 Pusher class 有关,它是命名空间的。 所以,我的问题是 "How do I prevent Composer over-writing my changes, next time I composer update, and also, why am I not able to avoid this editing of the Composer installed package by referring to the global namespace from within my own class?" 比如我自己的 PusherConnect class

public function __construct($app)
    {
        $this->app = $app;

        $pusher = new \Pusher(

顺便说一句,Pusher 库似乎曾经被命名空间,但不再是:https://github.com/pusher/pusher-http-php/commit/fea385ade9aede97b37267d5be2fce59d0f1b09d

提前致谢

如果您想修改随 Composer 引入的库并保留更改(但不向该包提交拉取请求),请将其移出您的 vendor 目录并开始使用您的版本控制对其进行跟踪系统。不利的一面(以及为什么人们不经常这样做)是现在必须由您手动处理对该包的任何错误修复或改进。

PSR-4 Autoloading 和 Namespaces 似乎会出现在 Pusher Library 的下一个版本中。 与此同时,我听从了 How to require a fork with composer 的建议并创建了我自己的 Pusher 库的分支,然后更新了我的 composer.json 以需要来自 github 的这个分支版本,我已将其命名空间。

The problem appears to be related to instantiating the non-namespaced Pusher class from within my own class, which is namespaced.

似乎你已经通过要求命名空间分支解决了这个问题,但无论如何:

如果您在命名空间 class 中使用 new Pusher,则 PHP 将尝试在此命名空间下查找 class:Smawt\Helpers\ 并且会失败使用 "Class not found",因为 Smawt\Helpers\Pusher 不存在于此命名空间内 - 没有映射。

通过使用前导反斜杠作为前缀 new \Pusher,您指的是来自命名空间 class 中的全局命名空间。另一种方法是在顶部 use \Pusher; 添加一个 use 语句,然后只添加 $obj = new Pusher.

两者都可以工作,因为 Composer 会生成自动加载文件,在获取包之后,您正在获取的包定义了一个基于 classmap 的自动加载:"classmap": [ "lib/" ]。因此,class Pusher 映射到 /vendor/pusher/pusher-php-server/lib/Pusher.php.

a) 带前导反斜杠的前缀

namespace Smawt\Helpers;

class PusherConnect
{
    protected $app;

    public function __construct($app)
    {
        $this->app = $app;

        $pusher = new \Pusher(

a) 使用语句

namespace Smawt\Helpers;

use \Pusher;

class PusherConnect
{
    protected $app;

    public function __construct($app)
    {
        $this->app = $app;

        $pusher = new Pusher(