PHP 命名空间与 Phalcon、Vagrant、Apache2 的冲突

Posted

技术标签:

【中文标题】PHP 命名空间与 Phalcon、Vagrant、Apache2 的冲突【英文标题】:PHP Namespace collision with Phalcon, Vagrant, Apache2 【发布时间】:2015-11-14 17:50:25 【问题描述】:

我有一个奇怪的问题,我可以将其最好地描述为“命名空间泄漏”。我已经设置了一个运行 Apache2 和 VHosts 设置的 vagrant box,以根据域和子域复制生产服务器。我已经相应地编辑了我的本地机器的主机文件,并且我的 VHosts 工作正常。

我还创建了一个用 Phalconphp 编码的框架/基础应用程序。这是一个多模块化应用程序,具有开发应用程序所需的所有通用功能(实际上是重新开发大量非常旧的、过时的应用程序)。骨架应用运行良好。

我遇到的问题是,如果我在浏览器中访问 app1.dev,它就可以工作。然后,如果我转到 app2.dev,app2 显然是在尝试从 app1 加载一些组件 - 视图等,并给出错误。但是,关闭浏览器并转到 app2.dev 重试,现在可以正常工作了。然后转到 app1.dev,它现在已损坏并试图从 app2 加载组件!我设法将这种奇怪的行为追溯到命名空间冲突。

它必须是命名空间冲突,因为我的应用程序都是基于骨架应用程序并使用它的命名空间,这对于应用程序的通用部分显然是相同的 - 模块,例如App\backendApp\frontend 等。如果在一个损坏的应用程序上,我在浏览器中导航到该应用程序的唯一部分,因此具有唯一的命名空间,它工作正常,因为没有冲突!还有一些应用程序是用不使用命名空间的 Codeigniter3 编码的,这些应用程序没有这个问题。它只影响带有命名空间的 Phalcon 应用程序。

我会补充一点,每个应用程序都使用.htaccess 将请求定向到位于public/ 目录中的前端控制器。

Options FollowSymLinks
<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteRule  ^$ public/    [L]
    RewriteRule  (.*) public/$1 [L]
</IfModule>

我想知道.htaccess 是否是问题所在,但我想我已经排除了这种可能性。它正在做它应该做的事情。

这是我在 apache 中的 VHost 设置之一的示例 - 它们都遵循这种模式。

<VirtualHost *:80>
    ServerName app1.dev
    ServerAlias www.app1.dev
    DocumentRoot /vagrant/www/app1
    <Directory "/vagrant/www/app1">
            Options Indexes Followsymlinks
            AllowOverride All
            Order allow,deny
            Allow from All
            Require all granted
    </Directory>
</VirtualHost>

更改每个应用程序中的所有命名空间将是一项非常重要的工作,我认为没有必要这样做。我不认为这应该是生产服务器上的问题,因为它使用 CloudLinux/Centos 和 WHM,但有点担心!

显然,命名空间不应该在不同的文档路径和 VHost 之间发生冲突,对吧?我错过了什么?

【问题讨论】:

可能是您的虚拟主机有问题。在模块化 phalcon 项目中,您的所有请求都发送到 /app/index.php。显示不同模块的方式是通过应用程序中的路由器。默认路由是/module/controller/action/params。如果不知道您如何配置设置以及如何设置所有 vhost 文件,则很难找出错误。 感谢您的评论。不,它不是虚拟主机。我已将其归结为 volt 编译器引擎的问题。似乎有些方式,当视图 phtml 文件尚不存在时,伏特正在寻找另一个应用程序的路径。我还没有时间对此进行进一步调查。 这是有道理的。虽然这就是为什么我说在不知道您的设置的情况下很难诊断:) 【参考方案1】:

我已经在 Apache 中为每个应用使用不同的本地 IP 解决了类似的问题:

/etc/hosts

127.1.0.1   edu.l
127.1.1.1   tech.l
...

/etc/apache2/sites-available/001-blogs.conf

<VirtualHost edu.l:80>
    ServerName edu.l

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/blog/edu

    ErrorLog $APACHE_LOG_DIR/edu.error.log
    CustomLog $APACHE_LOG_DIR/edu.access.log combined

</VirtualHost>

<VirtualHost tech.l:80>
    ServerName tech.l

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/blog/tech

    ErrorLog $APACHE_LOG_DIR/tech.error.log
    CustomLog $APACHE_LOG_DIR/tech.access.log combined

</VirtualHost>
...

您可以在 hosts 中省略配置名称,并在 .conf 中使用 IP。

它之所以有效,是因为如果您在相同的 IP 和端口上定义几个应用程序,Apache 似乎会记住它正在处理的目录和不匹配的文件。

【讨论】:

以上是关于PHP 命名空间与 Phalcon、Vagrant、Apache2 的冲突的主要内容,如果未能解决你的问题,请参考以下文章

php Phalcon注册命名空间

phalcon: router规则与解析,已经生成router的链接地址

phalcon环境的搭建和dll扩展下载与选择

PHP命名空间与use

php设计模式--命名空间与自动载入

phalcon:数据库分库,读写分离,负载均衡 系统方法执行顺序