Migrate phalcon version 3.x to version 4
其實 phalcon 4 已經release很久了,我一直拖著沒有把手邊的系統從 3.x 做升級,但總有該面對的一天
其實最後一根稻草是 phalcon 3.x 只支援到 php 7.3, 之後的 php 7.4 跟 php 8 都不支援,除非自己從 source code compile 才有可能。
安裝phalcon 4過程大致上跟 3.x 版差異不大,要比較注意的是要記得安裝 php-psr。
sudo apt-get update sudo apt-get install -y php7.4 apache2 sudo apt-get install -y php7.4-opcache php-apcu php7.4-mbstring php7.4-zip php7.4-xml php7.4-mysql php7.4-json php7.4-gd php7.4-gmp php7.4-curl php-psr sudo apt-get install -y wget sudo apt-get install -y curl wget http://pear.php.net/go-pear.phar php go-pear.phar curl -s "https://packagecloud.io/install/repositories/phalcon/stable/script.deb.sh" | sudo bash sudo apt-get install php7.4-phalcon sudo apt-get install libapache2-mod-php
過去舊的 phalcon 3.4 project 我都是用 devtool 工具生成 template,所以最直接需解決的是這些舊專案怎麼在 4.x 的環境中正常運作。
修改public/index.php
主要是handle request 的部分要做處理
$ diff -r /var/opt/www/new4.x/public/index.php /var/opt/www/old3.4/public/index.php 42,45c42,46 < $request = new Phalcon\Http\Request(); < $response = $application->handle($_GET['_url']); < $response->send(); --- > > echo $application->handle()->getContent();
大修改的 session 與 flash session
過去 3.x 中的 Flash Session 一整個變得不一樣, Phalcon\Flash\Session constructor 一整個大改,原本(參考文件 https://github.com/phalcon/docs-app/blob/master/3.4/ur-in/api/Phalcon_Flash.md)傳入 css settings 就可以。
另外 Session 也是,過去 new SessionAdapter() 之後就可以很方便使用,在 4.x 版中要正確指定好 adapter。
直接把整個 app/config/service.php 貼上來比較快
<?php declare(strict_types=1); use Phalcon\Escaper; use Phalcon\Flash\Direct as Flash; use Phalcon\Flash\Session as FlashSession; use Phalcon\Mvc\Model\Metadata\Memory as MetaDataAdapter; use Phalcon\Mvc\View; use Phalcon\Mvc\View\Engine\Php as PhpEngine; use Phalcon\Mvc\View\Engine\Volt as VoltEngine; use Phalcon\Session\Adapter\Stream as SessionAdapter; use Phalcon\Session\Manager as SessionManager; use Phalcon\Url as UrlResolver; /** * Shared configuration service */ $di->setShared('config', function () { return include APP_PATH . "/config/config.php"; }); /** * The URL component is used to generate all kind of urls in the application */ $di->setShared('url', function () { $config = $this->getConfig(); $url = new UrlResolver(); $url->setBaseUri($config->application->baseUri); return $url; }); /** * Setting up the view component */ $di->setShared('view', function () { $config = $this->getConfig(); $view = new View(); $view->setDI($this); $view->setViewsDir($config->application->viewsDir); $view->registerEngines([ '.volt' => function ($view) { $config = $this->getConfig(); $volt = new VoltEngine($view, $this); $volt->setOptions([ 'path' => $config->application->cacheDir, 'separator' => '_' ]); return $volt; }, '.phtml' => PhpEngine::class ]); return $view; }); /** * Database connection is created based in the parameters defined in the configuration file */ $di->setShared('db', function () { $config = $this->getConfig(); $class = 'Phalcon\Db\Adapter\Pdo\\' . $config->database->adapter; $params = [ 'host' => $config->database->host, 'username' => $config->database->username, 'password' => $config->database->password, 'dbname' => $config->database->dbname, 'charset' => $config->database->charset ]; if ($config->database->adapter == 'Postgresql') { unset($params['charset']); } return new $class($params); }); /** * If the configuration specify the use of metadata adapter use it or use memory otherwise */ $di->setShared('modelsMetadata', function () { return new MetaDataAdapter(); }); /** * Register the session flash service with the Twitter Bootstrap classes */ $di->set('flash', function () { $escaper = new Escaper(); $flash = new Flash($escaper); $flash->setImplicitFlush(false); $flash->setCssClasses([ 'error' => 'alert alert-danger', 'success' => 'alert alert-success', 'notice' => 'alert alert-info', 'warning' => 'alert alert-warning' ]); return $flash; }); /** * Start the session the first time some component request the session service */ $di->setShared('session', function () { $session = new SessionManager(); $files = new SessionAdapter([ 'savePath' => sys_get_temp_dir(), ]); $session->setAdapter($files); $session->start(); return $session; }); $di->set('flashSession', function () use ($session) { $session = $this->getSession(); $escaper = new Escaper(); $flashsession = new FlashSession($escaper, $session); $flashsession->setCssClasses([ 'error' => 'alert alert-danger', 'success' => 'alert alert-success', 'notice' => 'alert alert-info', 'warning' => 'alert alert-warning' ]); return $flashsession; });
完工後做點測試
<?php declare(strict_types=1); class TestController extends \Phalcon\Mvc\Controller { public function s1Action() { $this->session->set("name", "kevin durant"); $this->flashSession->error("test"); $this->response->redirect("test/s2"); } public function s2Action() { var_dump($this->session->name); } }
Request /test/s1 就會被 redirect 到 /test/s2 且印出 session[“name”] 與出現flash error message。
Reference:
- PHP 8 與 7 的差異
- https://www.programmersought.com/article/43914253346/
Original link: Phanix's Blog