弃用:call_user_func_array() 不应在 Symfony 路由器组件中静态调用

Deprecated: call_user_func_array() should not be called statically in Symfony Router Component

我像这样使用 symfony 路由器组件:

index.php

require '../application/core/Core.php';

$request = Request::createFromGlobals();

// Our framework is now handling itself the request
$app = new Framework\Core();

$response = $app->handle($request);

$response->send();

Core.php

namespace Framework;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;

class Core implements HttpKernelInterface
{
    /** @var RouteCollection */
    protected $routes;

    public function __construct()
    {
        $this->routes = new RouteCollection();
    }

    public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
    {
        // Load routes from the yaml file
        $fileLocator = new FileLocator(array(__DIR__));
        $loader = new YamlFileLoader($fileLocator);
        $routes = $loader->load('routes.yaml');

        // create a context using the current request
        $context = new RequestContext();
        $context->fromRequest($request);

        $matcher = new UrlMatcher($routes, $context);

        try {
            $attributes = $matcher->match($request->getPathInfo());
            print_r($attributes);
            $controller = $attributes['_controller'];
            $response = call_user_func_array($controller, $attributes);
        } catch (ResourceNotFoundException $e) {
            $response = new Response('Not found!', Response::HTTP_NOT_FOUND);
        }

        return $response;
    }

    public function map($path, $controller) {
        $this->routes->add($path, new Route(
            $path,
            array('controller' => $controller)
        ));
    }
}

routes.yaml中我添加:

index:
    path:     /test/foo
    methods: GET
    controller: 'App\Catalog\Controller\Home\IndexController::index'

我有这个索引控制器:

namespace App\Catalog\Controller\Home;

class IndexController extends \App\Core\Controller
{

    public function index()
    {
        $this->Language->load('common/home');

        $data['url'] = Config::get('URL');
        $data['title'] = $this->Language->get('text_title');
        //$data['Csrf_Token'] = Csrf::generate('csrf_token');
        $this->templates->addData($data, 'common/header');

        $headerData['scripts'] = $this->Document->getScripts('header');
        $headerData['data'] = $this->loadController('Common\HeaderController')->index();
        $this->templates->addData($headerData, 'common/header');

        echo $this->templates->render('index/index', $data);

    }
}

当我在浏览器中加载此 uri 时开始运行:test/foo 我看到此错误:

> Deprecated: call_user_func_array() expects parameter 1 to be a valid callback, non-static method App\Catalog\Controller\Home\IndexController::index() should not be called statically in /Applications/MAMP/htdocs/test/application/core/Core.php on line 42

Fatal error: Uncaught Error: Using $this when not in object context in /Applications/MAMP/htdocs/test/application/Catalog/Controller/Home/IndexController.php:16 Stack trace: #0 [internal function]: App\Catalog\Controller\Home\IndexController::index('App\Catalog\Con...', 'index') #1 /Applications/MAMP/htdocs/test/application/core/Core.php(42): call_user_func_array('App\Catalog\Con...', Array) #2 /Applications/MAMP/htdocs/test/public/index.php(98): Framework\Core->handle(Object(Symfony\Component\HttpFoundation\Request)) #3 {main} thrown in /Applications/MAMP/htdocs/test/application/Catalog/Controller/Home/IndexController.php on line 16

Core.php 文件中的第 42 行是:

$response = call_user_func_array($controller, $attributes);

我该如何解决这个错误?!

修复:

    $controllerResolver = new HttpKernel\Controller\ControllerResolver();
    $argumentResolver = new HttpKernel\Controller\ArgumentResolver();

    try {
        $request->attributes->add($matcher->match($request->getPathInfo()));

        $controller = $controllerResolver->getController($request);
        $arguments = $argumentResolver->getArguments($request, $controller);

        $response = call_user_func_array($controller, $arguments);

        } catch (ResourceNotFoundException $e) {
        $response = new Response('Not found!', Response::HTTP_NOT_FOUND);
     }