Can i use Symfony's Route Annotation in Non-Symfony Project

大憨熊 提交于 2020-06-17 02:52:41

问题


I already tried things here https://symfony.com/doc/master/components/routing.html But i couldn't make it.

<?php
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Bundle\FrameworkBundle\Routing\AnnotatedRouteControllerLoader;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
use Composer\Autoload\ClassLoader;
use Doctrine\Common\Annotations\AnnotationRegistry;

/** @var ClassLoader $loader */
$loader = require __DIR__.'/vendor/autoload.php';

AnnotationRegistry::registerLoader([$loader, 'loadClass']);

$loader = new AnnotationDirectoryLoader(
    new FileLocator(__DIR__.'/app/Controller/'),
    new AnnotatedRouteControllerLoader(
        new AnnotationReader()
    )
);

$routes = $loader->load(__DIR__.'/app/Controller/');

When i do that i get these mistakes

Fatal error: Uncaught Error: Class 'Symfony\Component\Config\Loader\FileLoader' not found in C:\xampp\htdocs\MyFw\vendor\symfony\routing\Loader\AnnotationFileLoader.php:25 Stack trace: #0 C:\xampp\htdocs\MyFw\vendor\composer\ClassLoader.php(444): include() #1 C:\xampp\htdocs\MyFw\vendor\composer\ClassLoader.php(322): Composer\Autoload\includeFile('C:\\xampp\\htdocs...') #2 [internal function]: Composer\Autoload\ClassLoader->loadClass('Symfony\\Compone...') #3 C:\xampp\htdocs\MyFw\vendor\symfony\routing\Loader\AnnotationDirectoryLoader.php(23): spl_autoload_call('Symfony\\Compone...') #4 C:\xampp\htdocs\MyFw\vendor\composer\ClassLoader.php(444): include('C:\\xampp\\htdocs...') #5 C:\xampp\htdocs\MyFw\vendor\composer\ClassLoader.php(322): Composer\Autoload\includeFile('C:\\xampp\\htdocs...') #6 [internal function]: Composer\Autoload\ClassLoader->loadClass('Symfony\\Compone...') #7 C:\xampp\htdocs\MyFw\index.php(14): spl_autoload_call('Symfony\\Compone...') #8 {main} thrown in C:\xampp\htdocs\MyFw\vendor\symfony\routing\Loader\AnnotationFileLoader.php on line 25


回答1:


When i print out $routes array it gives me this output, index function of TestController but how this will go there? Is there any special method for this?

Array
(
    [index] => Symfony\Component\Routing\Route Object
        (
            [path:Symfony\Component\Routing\Route:private] => /
            [host:Symfony\Component\Routing\Route:private] => 
            [schemes:Symfony\Component\Routing\Route:private] => Array
                (
                )

            [methods:Symfony\Component\Routing\Route:private] => Array
                (
                )

            [defaults:Symfony\Component\Routing\Route:private] => Array
                (
                    [_controller] => App\Controller\TestController::index
                )

            [requirements:Symfony\Component\Routing\Route:private] => Array
                (
                )

            [options:Symfony\Component\Routing\Route:private] => Array
                (
                    [compiler_class] => Symfony\Component\Routing\RouteCompiler
                )

            [condition:Symfony\Component\Routing\Route:private] => 
            [compiled:Symfony\Component\Routing\Route:private] => 
        )

)



回答2:


I was a bit curious to see what exactly was needed for this sort of thing to work under Symfony 5.

Start by loading five packages:

composer require symfony/routing
composer require symfony/config
composer require symfony/framework-bundle
composer require doctrine/annotations
composer require doctrine/cache

Then you need to tweak composer.json in order to autoload your app classes:

# composer.json
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        }
    }

And of course run "composer dump-autoload".

I then made a test controller:

# app/Controller/DefaultController.php
namespace App\Controller;

use Symfony\Component\Routing\Annotation\Route;

class DefaultController
{
    /**
     * @Route("/",name="index")
     */
    public function index()
    {
    }
    /**
     * @Route("/hello",name="hello")
     */
    public function hello()
    {
    }
}

After which, the loading code in the question worked as expected. So I won't bother repeating it here.

It's a bit strange that Symfony still relies on Doctrine to do some of it's annotation processing. It's important to note that the method AnnotationRegistry::registerLoader is depreciated so the code will have to be tweaked when Doctrine is eventually updated to 3.x. Or maybe the Doctrine annotation dependencies will get removed.

The other thing that is a bit of shame is that the AnnotatedRouteControllerLoader class requires loading the entire Symfony framework bundle. The class itself just takes care of setting the _controller route attribute. It might be worthwhile to clone the class into your own application and thus eliminate the need for dragging in the complete bundle.

If anyone should happen to stumble on this answer, here is a complete working example.



来源:https://stackoverflow.com/questions/59637483/can-i-use-symfonys-route-annotation-in-non-symfony-project

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!