Silexが2018年6月にEOLになることが発表されました。
SilexのEOLは非常に残念ですが、Symfony4+Flexにより、Symfonyが小さなアプリから大規模なシステムまでカバーできるようになったため、Silexはその役割を終えた、ということなのだろうなと考えています。
今回は、Silex-SkeletonをSymfony4+Flexの構成に移行してみたので、その手順を紹介したいと思います。
前提
- Silex-SkeletonをSymfony4+Flexの構成に移行します
- PHP7.1.3以上の環境が必要です
環境のセットアップ
まずはSilex-Skeltonをcloneし、動かすまで。
$ git clone https://github.com/silexphp/Silex-Skeleton.git
$ cd Silex-Skeleton
$ composer install
$ composer run
> echo 'Started web server on http://localhost:8888'
Started web server on http://localhost:8888
> php -S localhost:8888 -t web
http://localhost:8888 にアクセスし、Welcome to your new Silex Application!
が表示されればOKです。単純な表示確認なので、確認できればCTRL+Cでサーバを止めてもらって構いません。
ディレクトリ構成
Symfony4+Flexのディレクトリ構成は以下のディレクトリ構成にする必要があります。
symfony+flex/
├── assets/
├── bin/
│ └── console
├── config/
│ ├── bundles.php
│ ├── packages/
│ ├── routes.yaml
│ └── services.yaml
├── public/
│ └── index.php
├── src/
│ ├── ...
│ └── Kernel.php
├── templates/
├── tests/
├── translations/
├── var/
└── vendor/
Silex-Skeltonのディレクトリ構成を見てみると、以下のようになっています。
silex-skelton/
├── bin/
│ └── console
├── config/
│ ├── dev.php
│ └── prd.php
├── web/
│ └── index.php
├── src/
│ ├── app.php
│ ├── console.php
│ └── controllers.php
├── templates/
├── tests/
├── var/
└── web/
└── index.php
web
がpublic
に変わっている以外は、それほど違いはありません。いったんはこのままで進めます。
composer.jsonのマージ
Upgrading Existing Applications to Flexにある通り、ディレクトリ構成はほぼ同じなので、あとは依存関係をあわせていく必要があります。
Silex-Skeletonのcomposer.jonとSymfony+Flexのcomposer.jsonをマージします。
Symfony+Flexのcomposer.jsonはcomposer create-project symfony/skeleton xxx
とかで作っておくとわかりやすいです。
composer.jsonをがっちゃんこしたのが、以下になります。
// composer.json
- "php": ">=5.5.9",
+ "php": "^7.1.3",
+ "ext-iconv": "*",
+ "symfony/console": "^4.0",
+ "symfony/flex": "^1.0",
+ "symfony/framework-bundle": "^4.0",
+ "symfony/lts": "^4@dev",
+ "symfony/yaml": "^4.0",
"silex/silex": "~2.0",
"silex/web-profiler": "~2.0",
"symfony/asset": "~2.8|^3.0",
"symfony/browser-kit": "~2.8|^3.0",
"symfony/class-loader": "~2.8|^3.0",
"symfony/config": "~2.8|^3.0",
- "symfony/console": "~2.8|^3.0",
"symfony/css-selector": "~2.8|^3.0",
"symfony/debug": "~2.8|^3.0",
"symfony/finder": "~2.8|^3.0",
@@ -23,8 +28,18 @@
"symfony/twig-bridge": "~2.8|^3.0",
"symfony/validator": "~2.8|^3.0"
},
+ "require-dev": {
+ "symfony/dotenv": "^4.0"
+ },
"autoload": {
- "psr-0": { "": "src/" }
+ "psr-4": {
+ "App\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "App\\Tests\\": "tests/"
+ }
},
ここから、composer update --dev
すると、いくつかのファイルやディレクトリが生成されます。
// composer update後のgit status
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: .gitignore
modified: composer.json
Untracked files:
(use "git add <file>..." to include in what will be committed)
.env.dist
composer.lock
config/bundles.php
config/packages/
config/routes.yaml
config/routes/
config/services.yaml
flex/
public/
src/Controller/
src/Kernel.php
symfony.lock
translations/
Symfony+Flexで必要なディレクトリやファイルが生成されているのがわかります。
この状態で、php -S localhost:8000 -t public
し、http://localhost:8000/ にアクセスしてみましょう。※ドキュメントルートは、webではなくpublicを指定します。
多分こんなエラーが表示されると思います。
FileLoaderLoadException
The autoloader expected class "App\app" to be defined in file "/Users/xxx/repos/Silex-Skeleton/vendor/composer/../../src/app.php". The file was found but the class was not in it, the class name or namespace probably has a typo in /Users/xxx/repos/Silex-Skeleton/config/services.yaml (which is loaded in resource "/Users/xxx/repos/Silex-Skeleton/config/services.yaml").
これは、Symfonyがsrc以下のファイルをすべてコンテナに登録しようとしており、その際にapp.phpでエラーになっています。
config/services.yaml
を編集して除外しておきます。
// config/services.yaml
App\:
resource: '../src/*'
- exclude:'../src/{Entity,Migrations,Tests}'
+ exclude:'../src/{Entity,Migrations,Tests,app.php,console.php,controllers.php}'
app.phpの移行
ここから、Silexのアプリケーションを移行していきます。
Silexのエンドポイントであるweb/index.php
をみると、
// web/index.php
$app = require __DIR__.'/../src/app.php';
require __DIR__.'/../config/prod.php';
require __DIR__.'/../src/controllers.php';
$app->run();
のようになっています。
src/app.php
では、いくつかのサービスプロバイダが有効になっています。
// src/app.php
$app->register(new ServiceControllerServiceProvider());
$app->register(new AssetServiceProvider());
$app->register(new TwigServiceProvider());
$app->register(new HttpFragmentServiceProvider());
サービスプロバイダはSymfonyでは利用できないため、バンドル等に移行していく必要がありますが、ここで必要なのはTwigServiceProviderのみです。それ以外は、FrameworkBundleに含まれているため、特に何もする必要はありません。
TwigServiceProviderに対応するTwigBundleをインストールします。
$ composer req twig
でインストールします。
config/prd.php
をみると、
// config/prd.php
$app['twig.path'] = array(__DIR__.'/../templates');
$app['twig.options'] = array('cache' => __DIR__.'/../var/cache/twig');
のように定義されていますが、composer req twig
で、config/twig.yamlが生成されており、twigのパスなどはすでに設定されている状態になっています。
twig:
paths: ['%kernel.project_dir%/templates']
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
ここで、http://localhost:8000/ にアクセすると、やはりエラーになりますが、NotFoundHttpException
にエラー内容が変わっていると思います。※あとついでにエラー画面もSilexのものよりリッチになっています。
コントローラの移行
Silexのコントローラは、src/controllers.phpに定義されています。
// src/controlelrs.php
$app->get('/', function () use ($app) {
return $app['twig']->render('index.html.twig', array());
})
->bind('homepage')
;
Symfonyの場合、コントローラはsrc/Controller/
以下にコントローラのクラスを配置します。
コントローラはコマンドで生成するのが楽なので、以下のようにMakerBundle
をインストールします。
$ composer req annotations make
※MakerBundleがSensioExtraFrameworkBundleに依存するため、annotations
で合わせてインストールしています。
$ bin/console make:controller
でコントローラを作成します。
$ bin/console make:controller
Choose a name for your controller class (e.g. DeliciousGnomeController):
> IndexController
created: src/Controller/IndexController.php
作成されたIndexControllerをSilexのコントローラに合わせ、以下のように編集します。
// src/Contoroller/IndexController.php
class IndexController extends Controller
{
/**
- * @Route("/index", name="index")
+ * @Route("/", name="homepage")
*/
public function index()
{
// replace this line with your own code!
- return $this->render('@Maker/demoPage.html.twig', [ 'path' => str_replace($this->getParameter('kernel.project_dir').'/', '', __FILE__) ]);
+ return $this->render('index.html.twig');
}
}
http:localhost:8000 にアクセスし、Welcome to your new Silex Application!
が表示されれば成功です。
もし更新されない場合は、キャッシュされている場合もあるので$ bin/console cache:clear
でキャッシュをクリアしてみてください。
以上で、Silex-SkeletonをSymfony4+Flexの構成で動かすまでができました。
ただ、Silex-Skeletonはほんとに最小構成なので、実際に運用されているシステムの場合は、他にも色々移行する必要があるかと思います。
無理にSilexのまま移植していくよりかは、SymfonyのSkeletonの上に載せ替えていくほうが楽かな、と思いました。
次項で各種サービスプロバイダの移行先バンドル・ライブラリを調べてみたので、参考にしてみてください。
各種サービスプロバイダの移行
Silex-Skeletonは必要最小限の構成のため、各種サービスプロバイダを利用している場合は、それぞれSymfonyの各バンドルやライブラリへ移行する必要があります。
Silexの公式で紹介されているサービスプロバイダの移行先バンドルは以下になります。
AssetServiceProvider
FrameworkBundleに含まれているため、バンドルのインストールは不要です。
composer req asset
でasset componentをインストールすれば利用できます。
CsrfServiceProvider
FrameworkBundleに含まれているため、バンドルのインストールは不要です。
composer req symfony/security-csrf
でsecurity-csrfをインストールすれば利用できます。
DoctrineServiceProvider
Doctrine Bundleをインストールします。
composer req doctrine
でインストールできます。
FormServiceProvider
Form Componentをインストールします。
composer req form
でインストールできます。
HttpCacheServiceProvider
FrameworkBundleに含まれているため、バンドルのインストールは不要です。
HttpFragmentServiceProvider
FrameworkBundleに含まれているため、バンドルのインストールは不要です。
LocaleServiceProvider
FrameworkBundleに含まれているため、バンドルのインストールは不要です。
MonologServiceProvider
Monolog Bundleをインストールします。
composer req monolog
でインストールできます。
RememberMeServiceProvider
FrameworkBundleに含まれているため、バンドルのインストールは不要です。
SecurityServiceProvider
SecurityBundleをインストールします。
composer req security
でインストールできます。
SerializerServiceProvider
serializer componentをインストールします。
composer req symfony/serializer
でインストールできます。
ServiceControllerServiceProvider
FrameworkBundleに含まれているため、バンドルのインストールは不要です。
SessionServiceProvider
FrameworkBundleに含まれているため、バンドルのインストールは不要です。
SwiftmailerServiceProvider
SwiftmailerBundleをインストールします。
composer req mail
でインストールできます。
TranslationServiceProvider
translation componentをインストールします。
composer req symfony/translation
でインストールできます。
TwigServiceProvider
TwigBundleをインストールします。
composer req twig
でインストールできます。
ValidatorServiceProvider
validator comoponentをインストールします。
composer req symfony/validator
でインストールできます。
VarDumperServiceProvider
DebugBundleをインストールします。
composer req debug-pack
でインストールできます。
以上です。
Symfonyを触り始めてまだ2〜3週間程度なので、移行先のバンドルやライブラリについては誤りがあるかもしれません。もし間違いなどありましたらご指摘いただけるとありがたいです。