symfony2:类加载/命名空间处理-prod/dev环境之间的差异


symfony2: class loading/namespace handling - difference between prod/dev environments?

symfony2的app_dev.php和app.php或dev/prod环境(symfony 2.8.4)在类自动加载和命名空间处理方面到底有什么区别?

当我在开发环境中通过app_dev.php运行它时,一切都很好,当我在prod中通过app.php运行它时我得到一个内部服务器错误500(symfony的prod.log中没有写入任何内容)。查看apache的error.log,我看到:

PHP Fatal error:  Class 'SSMCRM''Common''ProductionTemplateMapper' not found in /var/[...]

是的,我清除了戳缓存。。。

app.php:

use Symfony'Component'HttpFoundation'Request;
/**
 * @var Composer'Autoload'ClassLoader
 */
$loader = require __DIR__.'/../app/autoload.php';
include_once __DIR__.'/../app/bootstrap.php.cache';
// Enable APC for autoloading to improve performance.
// You should change the ApcClassLoader first argument to a unique prefix
// in order to prevent cache key conflicts with other applications
// also using APC.
/*
$apcLoader = new Symfony'Component'ClassLoader'ApcClassLoader(sha1(__FILE__), $loader);
$loader->unregister();
$apcLoader->register(true);
*/
//require_once __DIR__.'/../app/AppCache.php';
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
//$kernel = new AppCache($kernel);
// When using the HttpCache, you need to call the method in your front controller instead of relying on the configuration parameter
//Request::enableHttpMethodParameterOverride();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

app_dev.php:

<?php
use Symfony'Component'HttpFoundation'Request;
use Symfony'Component'Debug'Debug;
// If you don't want to setup permissions the proper way, just uncomment the following PHP line
// read http://symfony.com/doc/current/book/installation.html#checking-symfony-application-configuration-and-setup
// for more information
//umask(0000);
// This check prevents access to debug front controllers that are deployed by accident to production servers.
// Feel free to remove this, extend it, or make something more sophisticated.
if (isset($_SERVER['HTTP_CLIENT_IP'])
    || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
    || !(in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1',
                                                  '192.168.33.1', //for vagrant box
        )) || php_sapi_name() === 'cli-server')
) {
    header('HTTP/1.0 403 Forbidden');
    exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}
/**
 * @var Composer'Autoload'ClassLoader $loader
 */
$loader = require __DIR__.'/../app/autoload.php';
Debug::enable();
$kernel = new AppKernel('dev', true);
$kernel->loadClassCache();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

在autoload.php中,我将我们的遗留类添加到加载器中:

$loader->add('SSMCRM', __DIR__.'/../web/legacy/classes');

我发现了故障。对于现在直接调用的每个遗留PHP文件,我们都有一条通往包装器的路径(以使遗留代码中的symfony功能可用)。我生成了控制器,它的路由名称和路径来自真实的URL,所以在第一步中,我们不需要重写所有链接和JavaScriptAJAX调用,也不需要稍后更容易地进行查找/替换操作。结果是这样的:

/**
 * @Route(
 * path="ajax/ajax_admin_vorlagen_web2print_detail.php",
 * name="pages/admin/ajax/ajax_admin_vorlagen_web2print_detail.php",
 * options={"expose"=true}
 * )
 */
public function ajax_admin_vorlagen_web2print_detailAction()
{
    return $this->returnLegacyResponse('pages/admin/ajax/ajax_admin_vorlagen_web2print_detail.php');
}

这在开发环境中运行得非常好,symfony的路由被执行,我们得到了相应的操作。但在prod环境中,symfony似乎首先查找文件本身(也许是为了提高速度?),如果文件存在,则跳过路由匹配。如果直接调用我们的文件,就没有symfony自动加载器,我们最近删除了遗留的自动加载器。这就是为什么这节课不见了。。。

因此,简单的解决方案是重命名所有受影响的路径(例如,删除".php")。

我在文档中找不到prod/dev环境在内核处理方面的任何差异(