Phalcon - 快速指南
Phalcon - 概述
Phalcon 是 PHP 的最新框架之一,由一群热情的开发人员开发。Phalcon 是一个松散耦合的框架,这意味着它允许根据应用程序的需求将其对象视为粘合组件。
与 PHP 中的其他框架(传统或现有)相比,Phalcon 提供了一些独特的功能。以下是 Phalcon 的一些最突出的功能 −
它是一个全栈开源框架。
用户只需很少的代码即可利用多个组件。
它可以根据需要用于创建独立的框架。例如,如果我们只需要 Phalcon 的缓存组件,我们可以在任何用纯 PHP 或使用框架编写的应用程序中使用它。
对于了解 模型-视图-控制器 (MVC) 和 对象关系建模 (ORM) 的开发人员来说,使用 Phalcon 就像小菜一碟。
性能
Phalcon 的性能是其区别于其他传统 PHP 框架的一个特点。Phalcon 结合了 PHP 和 C;它们每个都可以用作独立模块。 Phalcon 以更快的速度考虑了每个请求的编译,这使得一切看起来都是开箱即用的。
C 语言
Phalcon 与 C 兼容,这提高了编译速度。此外,C 与 Phalcon 结合提供对象关系映射 (ORM),从而提供与所创建模型的一致性。在 Phalcon 中创建的每个模型都与关系数据库的表相关联。Phalcon 中的 ORM 纯粹用 C 实现。
开发人员工具
开发人员工具用于开发 Web 应用程序。这些工具有助于生成结合了所有功能(C - 创建、R - 读取、U - 更新、D - 删除)的脚手架应用程序。开发者工具还包括对在 Phalcon 中实现的第三方库的可扩展支持。
对象关系映射
Phalcon 支持广泛的数据库。它不仅限于访问关系数据库。它支持关系型和非关系型数据库,这就像为 Phalcon 框架锦上添花。
Phalcon 与其他框架的比较
下表重点介绍了 Phalcon 与其他流行框架(如 Yii 和 Laravel)的不同之处。
Yii | Laravel | Phalcon | |
---|---|---|---|
项目类型 | Yii 有助于创建大型项目,如论坛、门户、CMS、RESTful Web 服务、等。 | Laravel 用于构建 Web 应用程序。它以精湛和复杂的语法而闻名。 | Phalcon 用于设计各种项目。 |
数据库支持 | Yii 支持所有关系和非关系数据库。 | Laravel 支持所有关系数据库。 | Phalcon 对关系和非关系数据库提供同等支持。 |
语言 | Yii 框架纯粹用 PHP 编写。 | Laravel 用 PHP 编写,遵循 MVC 模式。 | Phalcon 包含 PHP 和 C。 |
可扩展性 | Yii 对于中小型项目而言具有很高的可扩展性。 | 对于所有类型的项目而言,Laravel 的可扩展性都很高。 | 适合中型项目。 |
性能 | 相对较低。 | 高,但与 Phalcon 相比较低。 | 高性能。 |
Phalcon - 环境设置
先决条件 − 我们需要 WAMP/LAMP/MAMP 或 XAMPP 堆栈来安装此框架。
以下是在 Windows 中安装 Phalcon 框架的步骤。
步骤 1 − Phalcon 安装完全依赖于 dll 文件。DLL(动态链接库)为 Phalcon 创建所需的包和插件。
以下链接用于下载 dll 文件 − https://phalconphp.com/en/download
步骤 2 − 下载所需的 dll 文件。检查系统的适当配置并下载所需的 dll 文件。下载文件后,将 phalcon-php.dll 解压到 xampp 文件夹中的 /php/ext。
步骤 3 −编辑 php.ini 文件 中的路径,使其以与其他 .dll 文件类似的方式进行配置。
步骤 4 − 编辑路径后,重新启动 xampp/wamp 堆栈。正确设置 dll 文件后,它将在仪表板中清晰可见。
步骤 5 −下载软件包后,在系统属性中设置路径变量。
步骤 6 − dll 文件和 Phalcon 工具一起帮助创建项目/Web 应用程序。用户可以通过命令提示符验证 Phalcon 框架是否已成功安装。输出将显示如下屏幕截图所示。
步骤 7 − 收到此必要的输出后,使用以下命令创建项目 −
phalcon create-project <project-name>
将显示以下输出。
第 8 步 − Web 应用程序已成功创建。单击以下 URL − http://localhost/demo1
将显示输出,如以下屏幕截图所示。这是 Phalcon PHP 的欢迎页面。
Phalcon - 应用程序结构
在本章中,我们将讨论 Phalcon 的应用程序结构。以下是 Phalcon 项目的完整目录结构。
有一个根文件夹被视为代码库,可供 Web 服务器公开使用。它也被称为Web 目录。Web 根目录之外的其他文件夹对于 Web 服务器和 Phalcon 项目而言是无法访问的。
创建项目后,目录结构将在wamp/xampp文件夹中显示如下。考虑我们在上一章中创建的项目。
以下是项目的文件夹和子文件夹。
App
此文件夹包含所有重要的脚本文件和文件夹。完整的 Web 应用程序是基于"app"文件夹设计的。配置文件有助于协助顺利运行应用程序所需的配置。
以下是给定 Phalcon Web 应用程序的 app 文件夹的详细视图。
它由配置、控制器、库、迁移、模型和视图组成。
配置
Phalcon 中 Web 应用程序所需的所有配置都包含在此文件夹中。它包括与数据库连接、要添加的第三方库(如果有)以及要包含的服务相关的信息。
控制器
所有控制器都包含在此文件夹中。它们用于处理请求并生成响应。
库
Web 应用程序的第三方库(除现有的 Phalcon 框架外)。
迁移
此子文件夹包含与数据迁移相关的所有文件,也可以在任何其他框架中使用。
模型
模型包括与数据库交互所需的所有逻辑。它实际上用于数据表示。
视图
它构成了与 Web 应用程序相关的所有视图。这些视图在控制器的帮助下显示给最终用户。
缓存
此目录包含与缓存相关的数据,有助于提高性能。
公共
它包括用于资产管理的所有文件夹,包括 CSS、JavaScript、要上传的文件和一些元数据。
.htaccess 文件
在 Apache Web Server 软件上运行的 Web 服务器使用 .htaccess 作为配置文件。当它被放置在目录中时,服务器启动后就会加载所有必要的配置。
例如,可以使用 .htaccess 文件配置网站,使其仅对特定 IP 地址可用。
Phalcon - 功能
模型视图控制器 (MVC) 是一种用于开发基于 Web 的应用程序的软件设计和结构模式。此软件架构将信息的表示与用户与信息的交互分开。
MVC 模型使用三个逻辑层定义 Web 应用程序。
模型
模型是代表知识的对象。模型与其部分之间应存在一对一关系。它包括用于数据库连接和执行 CRUD 操作的所有逻辑。
视图
视图是其模型的可视化表示。视图与模型或其部分交互,并从模型中获取演示所需的数据。这是通过发送请求和接收适当的响应来实现的。视图包括最终用户看到的所有数据。
控制器
控制器充当用户和系统(模型和视图)之间的中介。它接受来自用户的请求,通过视图将其发送到模型。模型对其进行操作并将响应发送到控制器,该响应通过视图作为输出显示给最终用户。
控制器接收此类用户输出并将其转换为适当的消息。这些消息被视图用来显示为适当的响应。
Phalcon 中的工作流程
Phalcon 中的工作流程如下 −
用户与用户界面(视图)交互,并借助某些方法/事件维持交互。
这些方法和事件由控制器处理。
控制器通过更新用户的操作来访问模型。
视图使用模型生成适当的输出。
视图从其模型中获取数据。模型与视图没有直接交互。
用户界面等待进一步的用户交互,从新一轮的请求和响应开始。
Phalcon 包含模型、视图和控制器的目录。以下屏幕截图给出了更好的方案。
所有业务逻辑都在控制器中描述,模型与数据库交互,数据库包含与每个表相关的所有文件。
注意 −
在 Phalcon Web 应用程序中创建的所有控制器都扩展了 Phalcon\Mvc\Controller。
与数据库表关联的所有模型都扩展了 \Phalcon\Mvc\Model。
Phalcon - 配置
Web 应用程序的配置文件夹包含以下文件 −
- config.php
- loader.php
- services.php
config.php
它包含根据目录路径进行的数据库连接和路由配置。
<?php /* * Modified: preppend directory path of current file, because of this file own different ENV under between Apache and command line. * NOTE: please remove this comment. */ defined('BASE_PATH') || define('BASE_PATH', getenv('BASE_PATH') ?: realpath(dirname(__FILE__) . '/../..')); defined('APP_PATH') || define('APP_PATH', BASE_PATH . '/app'); return new \Phalcon\Config([ 'database' => [ 'adapter' => 'Mysql', 'host' => 'localhost', 'username' => 'root', 'password' => '', 'dbname' => 'test', 'charset' => 'utf8', ], 'application' => [ 'appDir' => APP_PATH . '/', 'controllersDir' => APP_PATH . '/controllers/', 'modelsDir' => APP_PATH . '/models/', 'migrationsDir' => APP_PATH . '/migrations/', 'viewsDir' => APP_PATH . '/views/', 'pluginsDir' => APP_PATH . '/plugins/', 'libraryDir' => APP_PATH . '/library/', 'cacheDir' => BASE_PATH . '/cache/', 'baseUri' => '/demo1/', ] ]);
loader.php
它扩展了现有的 \Phalcon\Loader() 类。加载器类注册了需要 Web 应用程序的目录。
<?php $loader = new \Phalcon\Loader(); /** * We're a registering a set of directories taken from the configuration file */ $loader->registerDirs( [ $config->application->controllersDir, $config->application->modelsDir ] )->register();
services.php
此文件关联了实现 Web 项目服务的所有函数。它实现了 Phalcon\Di 接口。它还通过加载服务来实现服务的依赖注入。
基本上,config 文件夹中的 services.php 文件充当所有服务的容器。此接口有助于初始化所有服务,如数据库连接、设置 cookie、创建新会话或连接 NoSQL 数据库。
<?php use Phalcon\Mvc\View; use Phalcon\Mvc\View\Engine\Php as PhpEngine; use Phalcon\Mvc\Url as UrlResolver; use Phalcon\Mvc\View\Engine\Volt as VoltEngine; use Phalcon\Mvc\Model\Metadata\Memory as MetaDataAdapter; use Phalcon\Session\Adapter\Files as SessionAdapter; use Phalcon\Flash\Direct as Flash; /** * 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([ 'compiledPath' => $config->application->cacheDir, 'compiledSeparator' => '_' ]); 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; $connection = new $class([ 'host' => $config->database->host, 'username' => $config->database->username, 'password' => $config->database->password, 'dbname' => $config->database->dbname, 'charset' => $config->database->charset ]); return $connection; });
Phalcon - 控制器
在 MVC 框架中,"C"代表控制器,指的是 Web 应用程序的交换机。控制器执行的操作有助于将参数传递给视图,以便它可以相应地显示和响应用户输入。
例如,如果我们通过包含用户名、电子邮件地址和密码等用户详细信息的注册表单进行注册,然后单击"提交"按钮,则用户插入或发布的数据将通过相关操作或功能通过控制器发送。
控制器的功能
控制器接受来自视图的输入并与相关模型交互。
它通过向模型发送命令来帮助更新模型的状态。它还可以向关联视图发送命令,这有助于根据模型的状态更改视图的显示。
控制器充当模型和视图之间的中介。
Phalcon 中的 MVC 工作流程
下图显示了 Phalcon 中的 MVC 工作流程
在 Phalcon 中创建控制器的步骤
步骤 1 − 在命令提示符的帮助下重定向到项目路径。请参阅以下屏幕截图。
如上图所示,"demo"是与 Phalcon PHP 框架关联的项目。
第 2 步 − 使用以下命令创建关联的控制器。
phalcon controller <controller-name>
以下是成功执行上述命令后的输出。
注意 − 控制器的类名必须带有后缀"controller"。这意味着 Phalcon 遵循了良好的命名约定。
默认情况下,在 Phalcon PHP 框架中创建应用程序时,它包含一个名为"IndexController"的控制器。默认情况下会调用此控制器来触发操作。
与其他扩展 \Phalcon\Mvc\Controller 的控制器不同,此控制器由 controller-base 扩展。
代码−
<?php class IndexController extends ControllerBase { public function indexAction() { echo "This is my first web application in Phalcon"; } }
输出 −
Phalcon - 模型
MVC 架构中的模型包括应用程序的逻辑。模型是与数据库交互的核心。它应该能够根据用户的请求管理记录的更新、删除、插入和获取。
要了解 Phalcon PHP 框架中的模型交互,应遵循以下步骤。
步骤 1 −创建数据库。
对于任何 LAMP、WAMP、XAMPP 软件堆栈,借助 phpmyadmin 数据库工具创建数据库非常容易。
以下是创建数据库的 SQL 查询。
创建数据库 <database-name>
步骤 2 − 在 phpmyadmin 部分中,单击数据库选项卡,输入数据库名称,然后单击创建按钮,如以下屏幕截图所示。
步骤 3 −数据库创建成功后,创建一个表,该表将有助于其关联以在 Phalcon 框架中创建模型。
使用以下查询创建一个名为"users"的新表。
DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(25), `emailid` varchar(50), `contactNumber` number PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8;
一旦创建了表,其结构将如以下屏幕截图所示。
步骤 4 − 要创建与我们在上述步骤中创建的"Users"表关联的模型,请打开命令提示符实例。重定向到适当的项目路径很重要。在此之前,必须检查数据库配置是否已正确设置,如以下屏幕截图所示。
步骤 5 − 使用以下命令在 Phalcon 框架中创建任何模型。
phalcon model <model-name>
以下是执行上述命令后的输出。
这意味着模型已成功创建。
第 6 步 − 模型成功创建位于 models 文件夹中。使用以下路径查看模型的创建位置。
C:\xampp\htdocs\demo1\app\models
以下是 Users.php 的完整代码。
<?php class Users extends \Phalcon\Mvc\Model { /** * * @var integer * @Primary * @Identity * @Column(type = "integer", length = 11, nullable = false) */ public $id; /** * * @var string * @Column(type = "string", length = 25, nullable = true) */ public $name; /** * * @var string * @Column(type = "string", length = 50, nullable = true) */ public $emailid; /** * * @var integer * @Column(type = "integer", length = 11, nullable = true) */ public $contactNumber; /** * Returns table name mapped in the model. * * @return string */ public function getSource() { return 'users'; } /** * Allows to query a set of records that match the specified conditions * * @param mixed $parameters * @return Users[] */ public static function find($parameters = null) { return parent::find($parameters); } /** * Allows to query the first record that match the specified conditions * * @param mixed $parameters * @return Users */ public static function findFirst($parameters = null) { return parent::findFirst($parameters); } }
第 7 步 − 控制器与模型和视图交互以获取必要的输出。与模型一样,使用以下命令终端创建控制器。
Phalcon 控制器 <controller-name>
成功执行上述命令后,输出如下。
以下是 UserController.php 的代码。
<?php class UsersController extends \Phalcon\Mvc\Controller { public function indexAction() { echo "Users Controller has been called"; } }
如果我们点击以下 URL − http://localhost/demo1/users
,将显示输出Phalcon - 视图
视图是呈现给最终用户的信息。视图可以视为具有要显示的适当响应的网页。响应通过与模型交互的控制器接收。
具体来说,在 Phalcon 中,视图由 Volt 代码、PHP 和 HTML 组成。在 Volt 模式下可以输入一组特殊分隔符。 {% ... %> 用于执行 for 循环或赋值等语句,{{ ... }> 用于将表达式的结果打印到模板中。
Phalcon 中的视图基本上分为两种类型 −
- Volt
- phtml
Volt
以下是我们在上一章中为项目 demo1 创建的输出的屏幕截图。
此输出是在文件 views/index/index.volt 的帮助下实现的。
Volt 文件的功能
它是一个用 javascript 编写的模板用 C 语言编写,与其他语言相比速度相当快。
它包含一组高度集成的组件,这些组件在 Phalcon 中非常有用。
它也可以用作独立组件。
Volt 被编译为纯 PHP 代码。
以下是 index.volt 的代码,默认情况下会为任何项目加载。
<!--<div class = "page-header"> <h1>Congratulations!</h1> </div>--> <p>This is my first web application in Phalcon </p> <!--<p>You're now flying with Phalcon. Great things are about to happen!</p> <p>This page is located at <code>views/index/index.volt</code></p>-->
分层渲染
Phalcon 中的视图支持分层渲染,并使用 Phalcon\Mvc\View 作为默认渲染组件。此组件使用 PHP 作为模板引擎,而 volt 文件则使用 C 作为模板语言。
这些视图应具有 .phtml 扩展名。给定项目的默认视图目录包含以下三个文件 −
操作视图 − 此视图用于执行特定操作。执行"显示"操作时会调用它。
控制器布局 − 此视图位于布局文件夹中。例如,C:\xampp\htdocs\demo\app\views\layouts。它调用与相应控制器关联的方法调用。布局中实现的代码将在需要时实现。
主布局 −此布局视图将调用主要操作,并将针对 Web 应用程序中的每个控制器或操作显示该操作。
.volt 和 .phtml 文件之间的区别
.volt | .phtml |
---|---|
当应用程序中设置的模板引擎使用 C 编写时,将使用 .volt 扩展名 | 当模板引擎本身是 PHP 时,将使用 .phtml |
它可以用作独立组件 | 它不能用作独立组件 |
Volt 视图被编译为 PHP 代码 | phtml 文件本身包含 PHP 代码,因此无需在 Phalcon 框架中进行编译 |
变量
使用"set"在模板中分配和更改变量。
声明数组
{% set fruit = ['Apple', 'Banana', 'Orange'] %}
声明字符串
{% set name = "John Kennedy" %}
注释
也可以使用 {# ... #> 分隔符将注释添加到模板中。注释内的所有文本在最终输出中都会被忽略。
{# note: this is a comment {% set price = 100; %} #}
Example
{% set fruits = ['Apple', 'Banana', 'Orange'] %} <h1>Fruits</h1> <ul> {% for fruit in fruits %} <li>{{ fruit|e }}</li> {% endfor %} </ul> {% set robots = ['Voltron', 'Astro Boy', 'Terminator', 'C3PO'] %} <ul> {% for robot in robots %} <li>{{ robot }}</li> {% endfor %} </ul>
输出
代码将生成以下输出屏幕 −
Phalcon - 路由
路由器组件允许定义映射到应接收请求的控制器或处理程序的路由。路由器根据收到的信息解析 URI。
Web 应用程序中的每个路由器都有两种模式 −
- MVC 模式
- 仅匹配模式
第一种模式非常适合与 MVC 应用程序一起使用。以下是在 Phalcon 中定义路由的语法。
$router = new Router(); // 定义路由 $router->add( "<URI-Name>", [ "controller" => "<controller-name>", "action" => "<action-name>", ] );
示例
为了搜索类别,让我们在 config 文件夹的 routes.php 中创建一个路由。
考虑创建一个路由,当我们调用 "UsersController" 时,它将调用方法 login。在这种情况下,建议创建一个映射给定 URL 的路由。
<?php $router = new Phalcon\Mvc\Router(); $router->add('/login', array( 'controller' => 'users', 'action' => 'login', )); return $router;
输出
代码将产生以下输出 −
Phalcon - 数据库连接
在本章中,我们将讨论与 Phalcon 相关的数据库连接。
数据库的创建和设计
我们将重点介绍如何为博客创建一个数据库,该数据库维护帖子以及根据用户条目分类。
数据库名称:blog-tutorial
用于创建数据库的查询 −
drop database blog-tutorial(如果存在) create database blog-tutorial
创建数据库后,数据库将按以下屏幕截图所示列出。
Phalcon 使用命令创建模型、控制器甚至项目。让我们看看它是如何工作的。
步骤 1 − 创建一个名为 blog-tutorial 的项目。
步骤 2 − 配置连接到我们为管理博客而创建的数据库的 Web 应用程序。
<?php return new \Phalcon\Config (array ( 'database' => array ( 'adapter' => 'Mysql', 'host' => 'localhost', 'username' => 'root', // 'dbname' => 'blog_tutorial', 'password' => '', 'name' => 'blog_tutorial', ), 'application' => array ( 'controllersDir' => __DIR__ . '/../../app/controllers/', 'modelsDir' => __DIR__ . '/../../app/models/', 'viewsDir' => __DIR__ . '/../../app/views/', 'baseUri' => '/blog-tutorial/', ) ));
Phalcon - 切换数据库
我们在应用程序中使用了 MySQL 数据库。如果我们想在中途更换数据库软件,这并不难,只要我们在新数据库中拥有相同的数据结构即可。
PostgreSQL
配置将连接到 PostgreSQL 数据库的 Web 应用程序。
这可以使用以下代码实现。服务将包括 Phalcon\Db\Adapter\Pdo\Postgresql
使用 Phalcon\Db\Adapter\Pdo\Postgresql; $config = [ 'host' => 'localhost', 'dbname' => 'blog_tutorial', 'port' => 5432, 'username' => 'root', 'password' => '' ]; $connection = new Postgresql($config);
SQLite
为了实现 SQLite 连接,配置应该使用 Phalcon\Db\Adapter\Pdo\Sqlite 抽象类进行扩展。
<?php use Phalcon\Db\Adapter\Pdo\Sqlite; $connection = new Sqlite(['dbname' => '/tmp/blog_tutorial.sqlite']);
Oracle
为了在 Phalcon 中实现 Oracle 数据库连接,配置应该使用 Phalcon\Db\Adapter\Pdo\Oracle 抽象类进行扩展。
<?php use Phalcon\Db\Adapter\Pdo\Oracle; $config = array ( "dbname" => "//localhost/blog_tutorial", "username" => "root", "password" => "" ); $connection = new Phalcon\Db\Adapter\Pdo\Oracle($config);
Phalcon - 脚手架应用程序
脚手架通常是指一种代码生成,我们将其指向 Web 应用程序数据库,从而创建一个基本的 CRUD(创建、读取、更新、删除)应用程序。
在设计 CRUD 应用程序之前,根据应用程序的需求设计数据库表非常重要。
步骤 1 − 创建一个包含所有 CRUD 操作的脚手架应用程序。
命令:phalcon scaffold <table-name>
Phalcon 的脚手架生成器一旦执行,将创建下表中描述的文件和文件夹。
步骤 2 − 创建索引页(phtml 和 volt 的组合)。
要包含在用户文件夹中的 index.phtml 中的代码。
<?php use Phalcon\Tag as Tag ?> <!DOCTYPE html> <html> <head> <meta charset = "utf-8"> <title>Blog Tutorial</title> <link rel = "stylesheet" type = "text/css" href = "http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrapcombined.min.css"/> <meta name = "viewport" content = "width = device-width, initial-scale = 1.0"> </head> <body> <div class = "navbar navbar-fixed-top"> <div class = "navbar-inner"> <div class = "container"> <a class = "btn btn-navbar" data-toggle = "collapse" datatarget = ".nav-collapse"> <span class = "icon-bar"></span> <span class = "icon-bar"></span> <span class = "icon-bar"></span> </a> <a class = "brand" href = "#">Blog Collection</a> <div class = "nav-collapse"> <ul class = "nav pull-left"> <li> <?php echo Phalcon\Tag::linkTo('index', 'Home Page') ?> </li> <?php if ($this->session->has('auth')) { ?> <li> <?php echo Phalcon\Tag::linkTo('posts/index', '+Posts') ?> </li> <li> <?php echo Phalcon\Tag::linkTo('categories/index', '+Categories') ?> </li> <li> <?php echo Phalcon\Tag::linkTo('users/logout', 'Log out') ?> </li> <?php } else { ?> <li> <?php echo Phalcon\Tag::linkTo('users/index', 'Log in') ?> </li> <?php } ?> </ul> </div> </div> </div> </div> <?php echo $this->getContent() ?> <script src = "http://netdna.bootstrapcdn.com/twitterbootstrap/2.2.1/js/bootstrap.min.js"></script> </body> </html>
默认文件 index.volt 将包含以下代码。
<?php echo $this->getContent() ?> <div align = "center"> <h1>Welcome!</h1> <p>Welcome to the blog collection of Phalcon</p> </div>
成功执行上述代码将产生以下输出。
步骤 3 − 使用相应的模型进行更改。
Users.php
<?php class Users extends \Phalcon\Mvc\Model { /** * @var integer * */ public $id; /** * @var string * */ public $login; /** * @var string * */ public $password; /** * Initializer method for model. */ public function initialize() { $this->hasMany("id", "Posts", "users_id"); } }
名为'initialize'的函数有助于在 Posts 表中实现 id 和 users_id 之间的关系,这意味着每个唯一用户在表中都有许多相关的帖子。
Posts.php
<?php class Posts extends \Phalcon\Mvc\Model { /** * @var integer * */ public $id; /** * @var string * */ public $title; /** * @var string * */ public $slug; /** * @var string * */ public $content; /** * @var string * */ public $created; /** * @var integer * */ public $users_id; /** * @var integer * */ public $categories_id; /** * Initializer method for model. */ public function initialize() { $this->belongsTo("users_id", "Users", "id"); $this->belongsTo("categories_id", "Categories", "id"); } }
函数'initialize'包含关系约束,其中提到了与表的外键和主键关系。
users_id 指的是"Users"表中的 id。
categories_id 指的是"Categories"表中的 id。
Categories.php
<?php class Categories extends \Phalcon\Mvc\Model { /** * @var integer * */ public $id; /** * @var string * */ public $name; /** * @var string * */ public $slug; /** * Initializer method for model. */ public function initialize() { $this->hasMany("id", "Posts", "categories_id"); } }
与用户模型类似,'initialize'函数指定它包含给定帖子的多个categories_id。
创建视图
以下是 Blog-tutorial-master 项目的完整结构。
用户成功登录后显示主页的关联视图是"index.phtml"。
<?php use Phalcon\Tag as Tag ?> <!DOCTYPE html> <html> <head> <meta charset = "utf-8"> <title>Blog Tutorial</title> <link rel = "stylesheet" type = "text/css" href = "http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrapcombined.min.css"/> <meta name = "viewport" content = "width = device-width, initial-scale = 1.0"> </head> <body> <div class = "navbar navbar-fixed-top"> <div class = "navbar-inner"> <div class = "container"> <a class = "btn btn-navbar" data-toggle = "collapse" datatarget = ".nav-collapse"> <span class = "icon-bar"></span> <span class = "icon-bar"></span> <span class = "icon-bar"></span> </a> <a class = "brand" href = "#">Blog Collection</a> <div class = "nav-collapse"> <ul class = "nav pull-left"> <li> <?php echo Phalcon\Tag::linkTo('index', 'Home Page') ?> </li> <?php if ($this->session->has('auth')) { ?> <li> <?php echo Phalcon\Tag::linkTo('posts/index', '+Posts') ?> </li> <li> <?php echo Phalcon\Tag::linkTo('categories/index', '+Categories') ?> </li> <li> <?php echo Phalcon\Tag::linkTo('users/logout', 'Log out') ?> </li> <?php } else { ?> <li> <?php echo Phalcon\Tag::linkTo('users/index', 'Log in') ?> </li> <?php } ?> </ul> </div> </div> </div> </div> <?php echo $this->getContent() ?> <script src = "http://netdna.bootstrapcdn.com/twitterbootstrap/2.2.1/js/bootstrap.min.js"></script> </body> </html>
Phalcon - 查询语言
Phalcon 查询语言 (PHQL) 也称为 PhalconQL,是一种高级 SQL 方言,它标准化了 Phalcon 支持的数据库系统的 SQL 查询。
它包含一个用 C 编写的解析器,用于转换目标 RDBMS 中的语法。
以下是 Phalcon 查询语言的一些主要功能列表 −
为了确保 Web 应用程序的安全,它使用绑定参数。
表被视为模型,而列被视为类属性。
所有数据操作语句均用于防止可能发生的数据丢失。
通过一次只调用一个 SQL 查询来防止 SQL 注入。
创建PHQL 查询
查询是通过实例化类 Phalcon\Mvc\Model\Query 创建的。
示例
// 实例化查询 $query = new Query( "SELECT * FROM Users", $this->getDI() ); // 执行查询并返回结果(如果有) $cars = $query->execute();
在前面的章节中,我们已经了解了名为 blog tutorial 的脚手架 Web 应用程序的工作原理。它包括按名称或 slug 搜索类别。
以下是 searchAction 的代码。
public function searchAction() { $numberPage = 1; if ($this->request->isPost()) { $query = Criteria::fromInput($this->di, "Categories", $_POST); $this->session->conditions = $query->getConditions(); } else { $numberPage = $this->request->getQuery("page", "int"); if ($numberPage <= 0) { $numberPage = 1; } } $parameters = array(); if ($this->session->conditions) { $parameters["conditions"] = $this->session->conditions; } // $parameters["order"] = "id"; $categories = Categories::find($parameters); if (count($categories) == 0) { $this->flash->notice("The search did not find any categories"); return $this->dispatcher->forward(array( "controller" => "categories", "action" => "index" )); } $paginator = new \Phalcon\Paginator\Adapter\Model(array( "data" => $categories, "limit"=> 10, "page" => $numberPage )); $page = $paginator->getPaginate(); $this->view->setVar("page", $page); }
在控制器中执行(突出显示)的 PHQL 查询将根据搜索条件获取所有结果。根据条件的任何搜索查询的结果都将如屏幕截图所示显示。
以下是成功执行上述代码后收到的输出。
PHQL 生命周期
作为一种高级语言,PHQL 为开发人员提供了根据需求个性化和定制各个方面的能力。
以下是在 Phalcon − 中执行的每个 PHQL 语句的生命周期。
每个 PHQL 语句都被解析并转换为中间表示 (IR),它完全独立于数据库系统实现的 SQL。
根据 Web 应用程序中使用的数据库系统,IR 转换为 SQL 语句。生成的SQL语句与模型相关联。
所有PHQL语句都解析一次并缓存在内存中。如果执行相同的语句结果,将有助于提高性能。
Phalcon - 数据库迁移
数据库迁移很重要,原因如下 −
数据库迁移有助于在指定的存储类型之间传输数据。
数据库迁移是指基于 Web 的应用程序从一个平台迁移到另一个平台的情况。
此过程通常用于跟踪过时的数据。
Phalcon 以以下方式执行数据库迁移过程 −
步骤 1 −在 xampp/wamp 目录中创建一个名为 "dbProject" 的项目。
步骤 2 − 使用适当的数据库连接配置项目。
<?php /* * Modified: preppend directory path of current file, because of this file own different ENV under between Apache and command line. * NOTE: please remove this comment. */ defined('BASE_PATH') || define('BASE_PATH', getenv('BASE_PATH') ?: realpath(dirname(__FILE__) . '/../..')); defined('APP_PATH') || define('APP_PATH', BASE_PATH . '/app'); return new \Phalcon\Config(['database' => [ 'adapter' => 'Mysql', 'host' => 'localhost', 'username' => 'root', 'password' => '', 'dbname' => 'demodb', 'charset' => 'utf8', ], 'application' => [ 'appDir' => APP_PATH . '/', 'controllersDir' => APP_PATH . '/controllers/', 'modelsDir' => APP_PATH . '/models/', 'migrationsDir' => APP_PATH . '/migrations/', 'viewsDir' => APP_PATH . '/views/','pluginsDir' => APP_PATH . '/plugins/', 'libraryDir' => APP_PATH . '/library/', 'cacheDir' => BASE_PATH . '/cache/', 'baseUri' => '/dbProject/', ] ]);
步骤 3 − 执行命令以迁移数据库"demodb"中包含的表。目前,它包含一个表"users"。
步骤 4 − 迁移的数据库文件存储在"app"文件夹内的迁移目录中。
因此,表已成功迁移。
了解迁移文件的结构
迁移文件具有一个唯一的类,该类扩展了 Phalcon\Mvc\Model\Migration 类。 Phalcon 中的 Migration 类包含 up() 和 down() 方法。up() 方法用于执行迁移,而 down 方法则回滚操作。
Users.php
<?php use Phalcon\Db\Column; use Phalcon\Db\Index; use Phalcon\Db\Reference; use Phalcon\Mvc\Model\Migration; /** * Class UserMigration_100 */ class UserMigration_100 extends Migration { /** * Define the table structure * * @return void */ public function morph() { $this->morphTable('user', [ 'columns' => [ new Column( 'Id', [ 'type' => Column::TYPE_INTEGER, 'notNull' => true, 'autoIncrement' => true, 'size' => 11, 'first' => true ] ), new Column( 'username', [ 'type' => Column::TYPE_VARCHAR, 'notNull' => true, 'size' => 40, 'after' => 'Id' ] ), new Column( 'email', [ 'type' => Column::TYPE_VARCHAR, 'notNull' => true, 'size' => 40, 'after' => 'username' ] ), new Column( 'password', [ 'type' => Column::TYPE_VARCHAR, 'notNull' => true, 'size' => 10, 'after' => 'email' ] ) ], 'indexes' => [new Index('PRIMARY', ['Id'], 'PRIMARY') ], 'options' => [ 'TABLE_TYPE' => 'BASE TABLE', 'AUTO_INCREMENT' => '3', 'ENGINE' => 'InnoDB', 'TABLE_COLLATION' => 'latin1_swedish_ci' ], ] ); } /** * Run the migrations * * @return void */ public function up() { } /** * Reverse the migrations * * @return void */ public function down() { } }
如上例所示,类 UserMigration_100 包含一个关联数组,该数组包含四个部分,分别是 −
Columns − 包含一组表列。
Indexes − 包含一组表索引。
References − 包含所有参照完整性约束(外键)。
Options − 包含一组表创建选项的数组。
如上例所示,数据库版本 1.0.0 已成功迁移。Phalcon 可能包含并运行多个迁移过程,具体取决于数据库内容的保存方式。
Phalcon - Cookie 管理
Cookie 也称为 浏览器 Cookie,是存储在浏览器中的小型文本文件。它保存与用户身份相关的所有信息。这些信息用于在用户浏览不同页面时验证用户身份。
Cookie 有两种不同类型 −
会话 Cookie − 这些类型的 Cookie 会保留在浏览器中并保留信息,直到浏览器关闭。一旦打开浏览器,它将被视为同一用户的新会话。
持久性 Cookie − 它具有规定的使用寿命,并在给定的使用寿命内保留在浏览器中。那些使用持久性 cookie 的网站会跟踪每个用户,即使用户关闭了浏览器也是如此。
现在让我们讨论一下 Phalcon 中的 cookie 是如何工作的。
Phalcon 中的 Cookie
Phalcon 使用 Phalcon\Http\Response\Cookies 作为 cookie 的全局存储。在向服务器发送请求时,Cookie 会存储在 Phalcon 中。
以下是设置 Cookie 的语法 −
$this->cookies->set( "<cookie-name>", "<cookie-value>", time );
考虑以下示例。使用以下代码,我们将在用户登录 Web 应用程序时创建用户的 cookie。
<?php class UsersController extends \Phalcon\Mvc\Controller { public function indexAction() { if ($this->cookies->has("login-action")) { // Get the cookie $loginCookie = $this->cookies->get("login-action"); // Get the cookie's value $value = $loginCookie->getValue(); echo($value); } $this->cookies->set( "login-action", "abc", time() + 15 * 86400 ); } }
加密的 cookie 将显示为输出。
描述
名为 "loginAction" 的 Cookie 已创建,值为 "abc"。
方法 "indexAction" 检查 cookie 是否存在并相应地打印值。
Cookie 的加密
Phalcon 中的 Cookie 在作为请求发送到服务器之前会进行加密,并在我们从服务器收到适当的响应后立即解密。这确保了授权用户的安全。
尽管具有加密和解密功能,但始终建议避免在 cookie 中存储敏感数据。 services.php 文件中包含了 cookie 加密的配置。
/** * 启用加密密钥来设置 Cookie 的值 */ $di->set( "cookies", function () { $cookies = new Cookies(); $cookies->useEncryption(false); return $cookies; } ); /** * 设置加密密钥 */ $di->set( "crypt", function () { $crypt = new Crypt(); $crypt->setKey('AED@!sft56$'); // 使用唯一的密钥! return $crypt; } );
注意 −
始终建议在向服务器发送 cookie 时使用加密。
如果不使用加密,所有内部应用程序都将暴露给攻击者。
还建议在 cookie 中存储小数据和文字。
Phalcon - 会话管理
会话是服务器端信息存储,有助于用户与网站或 Web 应用程序交互。每个会话都使用一个唯一的会话 ID 定义,每当浏览器发出 HTTP 请求时,该 ID 就会传递给 Web 服务器。每次会话 ID 都会与内部数据库配对,以便检索所有存储的变量。
Phalcon 中的会话
Phalcon 使用包含包装器的会话组件来访问会话数据。
以下是 Phalcon 中的功能 −
会话数据可以与同一域上的其他组件隔离。
根据应用程序的需求,可以借助会话适配器更改会话值。
在 Phalcon 中启动会话
所有会话活动都与适配器文件相关联,这些文件在 Web 应用程序的 /config 文件夹内的 Services.php 文件中声明。
/** * 启动会话某个组件第一次请求会话服务 */ $di->setShared('session', function () { $session = new SessionAdapter(); $session->start(); return $session; });
创建会话
步骤 1 − 创建一个会话控制器,用于实例化会话,以便可以适当地检索数据。
步骤 2 − 创建一个具有名称和值的会话。
<?php class SessionController extends \Phalcon\Mvc\Controller { public function indexAction() { //定义会话变量 $this->session->set("user-name", "Omkar"); //检查变量是否已定义 if ($this->session->has("user-name")) { //检索其值 $name = $this->session->get("user-name"); echo($name); } } }
上述代码产生以下输出。
删除会话
在 Phalcon 中,可以销毁会话或取消设置会话中的某些变量值。
以下是在会话中取消设置变量值的语法。
$this->session->remove(<variable-name>);
如上例所示,会话中创建的变量名称为 "data-content",可以使用以下代码将其删除。
public function removeAction() { // 删除与会话关联的会话变量 $this->session->remove("data-content"); };
以下是销毁完整会话的语法。
$this->session->destroy();
Phalcon - 多语言支持
Phalcon 包含一个组件 Phalcon\Translate,它提供多语言支持,对于创建可翻译成多种语言的网页非常有帮助。
它包含一个适配器,可帮助绑定数组并协助读取翻译消息。
示例
让我们在 Phalcon 中的 Translate 组件的帮助下创建一个输出,这将有助于根据建议的语言显示输出。
步骤 1 − Phalcon 为每个开发人员提供了组织翻译字符串的自由。考虑保留两个不同的文件,即:en.php(用于英语字符串)和fr.php(用于法语字符串)。
该文件将包含一个键值对数组,其中键是唯一的,而值将根据所需的翻译而有所不同。
en.php
<?php // app/messages/en.php $messagesContent = [ "bye" => "Good Bye", "hi-name" => "Hello %name%", "song" => "Your favorite song is %song%", ];
fr.php
<?php // app/messages/fr.php $messagesContent = [ "bye" => "Au revoir", "hello-name" => "Bonjour %name%", "song" => "Votre chanson préférée est %song%", ];
步骤 2 − 在应用程序中,创建一个 UserController,它将接受用于翻译的文件的参数。
<?php use Phalcon\Translate\Adapter\NativeArray; class UserController extends \Phalcon\Mvc\Controller { protected function getMessageTransalation() { // 询问最佳语言 // 以所需语言显示输出 require "en.php"; // 返回一个翻译对象 return new NativeArray( ["content" => $messagesContent,]); } public function indexAction() { $this->view->name = "Radhika"; $this->view->song= "Ton sourire m'ensorcelle Je suis fou de toi Le désir coule dans mes veines Guidé par ta voix"; $this->view->t = $this->getMessageTransalation(); } }
对于默认方法,需要两个参数,第一个是名称,第二个是用户最喜欢的歌曲。稍后,将调用函数 getMessageTranslation,该函数返回所需的输出。
现在,我们希望输出英文。
步骤 3 − 关联的 代码视图 demo\app\views\User\index.volt 将包含以下代码 −
<p><?php echo $t->_("hello-name", ["name" => $name]); ?></p> <p><?php echo $t->_("song", ["song" => $song]); ?></p>
如果我们希望完整的输出以法语显示,我们只需要更改文件名即可。
require "fr.php";
以下是法语的输出。
Phalcon - 资产管理
资产是指 Phalcon 中除现有框架之外的附加组件。 Phalcon 有一个资源管理器,它可以帮助管理所有资源组件,如 CSS 或 JS 文件。
常用的方法是 −
方法 | 重要性 |
---|---|
__construct(variable $options) | 初始化组件 Phalcon\Assets\Manager |
addCss(string $path, variable $local, variable $filter, variable $attributes) | 将"css"集合中的 CSS 资源添加到特定view |
addJs(string $path, variable $local, variable $filter, variable $attributes) | 将 JavaScript 资源添加到"js"集合 |
示例
考虑 Phalcon "vokuro" 的示例项目,它是添加 css 文件的最佳例证。它将包括用于调用所有 css 文件的 assets/Manager。
项目的默认控制器将调用所有 css 文件。
<?php namespace Vokuro\Controllers; use Phalcon\Assets\Manager; /** * Display the default index page. */ class IndexController extends ControllerBase { /** * Default action. Set the public layout (layouts/public.volt) */ public function indexAction() { $this->assets->addCss("public/style.css"); $this->view->setVar('logged_in', is_array($this->auth->getIdentity())); $this->view->setTemplateBefore('public'); } }
Style.css
div.remember { margin-top: 7px; color: #969696; } div.remember label { padding-top: 15px; } div.forgot { margin-top: 7px; color: #dadada; } footer { background: url("../img/feature-gradient.png") no-repeat scroll center 100% white; color: #B7B7B7; font-size: 12px; padding: 30px 0; text-align: center; } footer a { margin-left: 10px; margin-right: 10px; } table.signup td { padding: 10px; } table.signup .alert { margin-bottom: 0; margin-top: 3px; } table.perms select { margin-top: 5px; margin-right: 10px; } table.perms label { margin-right: 10px; } div.main-container { min-height: 450px; }
资产将在视图内进行管理,并将 css 文件显示为输出。
Index.volt
{{ content() }} {{ assets.outputCss() }} <header class = "jumbotron subhead" id = "overview"> <div class = "hero-unit"> <h1>Welcome!</h1> <p class = "lead">This is a website secured by Phalcon Framework</p> <div align = "right"> {{ link_to('session/signup', '<i class="icon-ok icon-white"> </i> Create an Account', 'class': 'btn btn-primary btn-large') }} </div> </div> </header>
输出
它将产生以下输出 −
Phalcon - 使用表单
所有 Web 应用程序都使用表单来接受用户的输入请求。数据作为输入被接受,然后被处理并保存在数据库中或执行任何其他操作。
Phalcon 包含一个名为 Phalcon\Forms 的组件,可帮助创建和维护表单。
考虑我们在前几章中创建的 Blog-tutorial 示例。它包含一个用于创建新类别的表单。
<?php echo \Phalcon\Tag::form(array("categories/create", "autocomplete" => "off")) ?> <table width = "100%"> <tr> <td align = "left"> <?php echo \Phalcon\Tag::linkTo(array("categories", "Go Back", "class" => "btn")) ?> </td> <td align = "right">< ?php echo \Phalcon\Tag::submitButton(array("Save", "class" => "btn")) ?> </td> <tr> </table> <?php echo $this->getContent(); ?> <div align = "center"> <h1>Create categories</h1> </div> <table align = "center"> <tr> <td align = "right"> <label for = "name">Name</label> </td> <td align = "left"> <?php echo \Phalcon\Tag::textField(array("name", "size" => 30)) ?> </td> </tr> <tr> <td align = "right"> <label for = "slug">Slug</label> </td> <td align = "left"> <?php echo \Phalcon\Tag::textField(array("slug", "size" => 30)) ?> </td> </tr> </table> </form>
输出 − 它将产生以下输出。
表单的输入字段在 Phalcon/tag 组件的帮助下呈现。表单中的每个元素都可以根据开发人员的要求进行呈现。
以下是呈现值的语法。
echo $form->render(element-name)
验证 −
一旦值在控制器中呈现,这些值将在模型的帮助下输入到数据库中。Phalcon 表单与验证组件集成以提供即时验证。可以为每个元素设置内置或自定义验证器。
<?php use Phalcon\Forms\Element\Text; use Phalcon\Validation\Validator\PresenceOf; use Phalcon\Validation\Validator\StringLength; $name = new Text( "Name" ); $name->addValidator( new PresenceOf([ "message" => "name is required", ]) ); $form->add($name);
输出 − 它将产生以下输出。
Phalcon - 对象文档映射器
在开始了解对象关系映射器 (ORM) 和对象文档映射器 (ODM) 的概念之前,了解 SQL 和 NoSQL 数据库之间的区别非常重要。
下表重点介绍了 SQL 和 NoSQL 之间的区别 −
SQL | NoSQL |
---|---|
它们也被称为关系数据库 (RDBMS) | 它们被称为非关系数据库或分布式数据库 |
数据库的结构由表和视图组成 | 它由基于文档的和图形数据库 |
它包含一个预定义模式 | 它有一个动态模式 |
它对于定义和操作数据非常强大 | 它对于将数据维护为文档集合非常强大 |
Phalcon 能够与 SQL 和 NoSQL 数据库进行映射。这是借助 NoSQL 数据库的对象文档映射器 (ODM) 和 SQL 数据库的对象关系映射器 (ORM) 实现的。
在 Phalcon 中,ORM 概念包括创建与给定表名关联的模型,正如我们在前面章节中看到的那样。它遵循所有引用完整性约束。
对象文档映射器 (ODM)
它是与 NoSQL 数据库关联的对象。顾名思义,它映射文档相关模块。 Phalcon 使用它来映射 MongoDB 等数据库。
示例
步骤 1 − 创建一个名为 "test" 的 MongoDB 数据库。我们将使用此数据库进行映射并获得适当的响应。
步骤 2 − 检查数据库中插入的记录。与之关联的命令是 −
db.collection.find()
可以观察到,每个文档都与 ObjectId 进行了映射,这是 ODM 的一个功能。ObjectId 的值是唯一的,稍后用于获取与该特定 Id 相关的所有存储数据。
步骤 3 − 为创建的数据库设置模型。模型是一个扩展 Phalcon\Mvc\Collection 的类。Test.php 模型将包含以下代码。
<?php use Phalcon\Mvc\Collection; class Test extends Collection { public function initialize() { $this->setSource("test"); } }
步骤 4 − 在 services.php 中配置项目,包括数据库连接。
// 简单的数据库连接到本地主机 $di->set( "mongo", function () { $mongo = new MongoClient(); return $mongo->selectDB("test"); }, true ); // 连接到域套接字,回退到本地主机连接 $di->set( "mongo", function () { $mongo = new MongoClient( "mongodb:///tmp/mongodb-27017.sock,localhost:27017" ); return $mongo->selectDB("test"); }, true );
步骤 5 − 在 TestController.php 的帮助下打印与 ObjectId 相关的值。
<?php use Phalcon\Mvc\Controller; class TestController extends Controller { public function index() { // 查找 _id = "5087358f2d42b8c3d15ec4e2" 的记录 $test = Test::findById("5819ab6cfce9c70ac6087821"); echo $test->data; } }
输出将显示与 objectId 匹配的数据。如果 objectId 与文档中的记录不匹配,则不会显示相应的输出,因为已获取记录数。
Phalcon - 安全功能
Phalcon 借助安全组件提供安全功能,可帮助执行某些任务,如密码哈希处理和跨站点请求伪造 (CSRF)。
哈希处理密码
哈希处理可定义为将固定长度的位字符串转换为指定长度的过程,且该过程不可逆。输入字符串的任何更改都会更改哈希数据的值。
哈希数据的解密是通过将用户输入的值作为输入并比较其哈希形式来进行的。通常对于任何基于 Web 的应用程序,将密码存储为纯文本是一种不好的做法。它很容易受到第三方攻击,因为有权访问数据库的人可以轻松获取任何用户的密码。
Phalcon 提供了一种简单的方法来以加密形式存储密码,该加密形式遵循 md5、base64 或 sh1 等算法。
如前几章所示,我们为博客创建了一个项目。登录屏幕接受用户的用户名和密码输入。要从用户那里接收密码并以特定形式解密,请使用以下代码片段。
然后将解密的密码与从用户那里接受的输入密码进行匹配。如果值匹配,则用户可以成功登录到 Web 应用程序,否则将显示错误消息。
<?php class UsersController extends Phalcon\Mvc\Controller { public function indexAction() { } public function registerUser() { $user = new Users(); $login = $this->request->getPost("login"); $password = $this->request->getPost("password"); $user->login = $login; // 存储哈希密码 $user->password = $this->security->sh1($password); $user->save(); } public function loginAction() { if ($this->request->isPost()) { $user = Users::findFirst(array( 'login = :login: and password = :password:', 'bind' => array( 'login' => $this->request->getPost("login"), 'password' => sha1($this->request->getPost("password")) ) )); if ($user === false) { $this->flash->error("Incorrect credentials"); return $this->dispatcher->forward(array( 'controller' => 'users', 'action' => 'index' )); } $this->session->set('auth', $user->id); $this->flash->success("You've been successfully logged in"); } return $this->dispatcher->forward(array( 'controller' => 'posts', 'action' => 'index' )); } public function logoutAction() { $this->session->remove('auth'); return $this->dispatcher->forward(array( 'controller' => 'posts', 'action' => 'index' )); } }
数据库中存储的密码采用 sh1 算法的加密格式。
一旦用户输入了正确的用户名和密码,用户就可以访问系统,否则将显示错误消息作为验证。
跨站点请求伪造 (CSRF)
这是一种迫使经过身份验证的 Web 应用程序用户执行某些不必要的操作的攻击。接受用户输入的表单容易受到此攻击。Phalcon 试图通过保护通过应用程序外部的表单发送的数据来防止此攻击。
每个表单中的数据都通过令牌生成来保护。生成的令牌是随机的,它与我们向其发送表单数据的令牌相匹配(主要通过 POST 方法在 Web 应用程序之外发送)。
代码:
<?php echo Tag::form('session/login') ?> <!-- Login and password inputs ... --> <input type = "hidden" name = "<?php echo $this->security->getTokenKey() ?>" value = "<?php echo $this->security->getToken() ?>"/> </form>
注意 − 在发送表单令牌时使用会话适配器非常重要,因为所有数据都将在会话中维护。
使用以下代码在 services.php 中包含会话适配器。
/** * 当某个组件第一次请求会话服务时启动会话 */ $di->setShared('session', function () { $session = new SessionAdapter(); $session->start(); return $session; });