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
