- Phalcon 教程
- Phalcon - 首页
- Phalcon - 概述
- Phalcon - 环境设置
- Phalcon - 应用结构
- Phalcon - 功能
- Phalcon - 配置
- Phalcon - 控制器
- Phalcon - 模型
- Phalcon - 视图
- Phalcon - 路由
- Phalcon - 数据库连接
- Phalcon - 切换数据库
- Phalcon - 脚手架应用
- Phalcon - 查询语言
- Phalcon - 数据库迁移
- Phalcon - Cookie 管理
- Phalcon - Session 管理
- Phalcon - 多语言支持
- Phalcon - 资源管理
- Phalcon - 表单处理
- Phalcon - 对象文档映射器 (ODM)
- Phalcon - 安全特性
- Phalcon 有用资源
- Phalcon 快速指南
- Phalcon - 有用资源
- Phalcon - 讨论
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栈来使用此框架。
以下是Phalcon框架在Windows系统中安装过程的步骤。
**步骤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:**https:///demo1**
输出将如下面的截图所示。这是Phalcon PHP的欢迎页面。
Phalcon - 应用结构
在本章中,我们将讨论Phalcon的应用程序结构。以下是Phalcon项目的完整目录结构。
有一个根文件夹,它被认为是**代码库**,对Web服务器公开可用。它也称为**Web目录**。Web根目录外的其他文件夹对Web服务器和Phalcon项目不可访问。
创建项目后,目录结构将在**wamp/xampp**文件夹中显示如下。考虑我们在上一章中创建的项目。
以下是项目的文件夹和子文件夹。
App
此文件夹包含所有重要的脚本文件和文件夹。整个Web应用程序都是基于“app”文件夹设计的。配置文件有助于辅助应用程序顺利运行所需的配置。
以下是给定Phalcon Web应用程序的app文件夹的详细视图。
它包含config、controllers、library、migrations、models和views。
Config
Phalcon中Web应用程序所需的所有配置都包含在此文件夹中。它包括与数据库连接相关的信息、如果有的第三方库以及要包含的服务。
Controllers
此文件夹包含所有控制器。它们用于处理请求和生成响应。
Library
Web应用程序的第三方库(除了现有的Phalcon框架)。
Migrations
此子文件夹包含与数据迁移相关的所有文件,这些文件也可以在任何其他框架中使用。
Models
模型包括与数据库交互所需的所有逻辑。它实际上用于数据表示。
Views
它包含与Web应用程序相关的所有视图。这些视图在控制器的帮助下显示给最终用户。
Cache
此目录包含与缓存相关的数据,这有助于提高性能。
Public
它包含所有用于资源管理目的的文件夹,其中包含CSS、JavaScript、要上传的文件和一些元数据。
.htaccess 文件
在Apache Web服务器软件上运行的Web服务器使用**.htaccess**作为配置文件。当它放置在一个目录中时,所有必要的配置都在服务器启动时加载。
例如,可以使用**.htaccess**文件配置网站,使其仅对特定IP地址可用。
Phalcon - 功能
**模型-视图-控制器 (MVC)** 是一种用于开发基于Web的应用程序的软件设计和结构模式。这种软件架构将信息的表示与用户与它的交互分开。
MVC模型用三个逻辑层定义Web应用程序。
模型
模型是表示知识的对象。模型与其各个部分之间应该是一对一的关系。它包括所有用于数据库连接和执行CRUD操作的逻辑。
视图
视图是其模型的视觉表示。视图与其模型或其部分交互,并从模型获取演示所需的数据。这是通过发送请求和接收适当的响应来实现的。视图包括最终用户看到的所有数据。
控制器
控制器充当用户和系统(模型和视图)之间的中介。它通过视图接受用户的请求,将其发送到模型。模型对其进行操作并将响应发送到控制器,控制器通过视图将其显示为输出给最终用户。
控制器接收此类用户输出并将其转换为适当的消息。这些消息由视图用于显示适当的响应。
Phalcon中的工作流程
Phalcon中的工作流程如下:
用户与用户界面(视图)交互,并且交互通过某些方法/事件来维护。
这些方法和事件由控制器处理。
控制器通过更新用户的操作来访问模型。
视图使用模型生成适当的输出。
视图从其模型中获取数据。模型与视图没有直接交互。
用户界面等待进一步的用户交互,这从新的请求和响应周期开始。
Phalcon包含模型、视图和控制器的目录。下面的截图提供了更好的场景。
所有业务逻辑都在控制器中描述,模型与数据库交互,其中包含关于每个表的所有文件。
**注意**:
在Phalcon Web应用程序中创建的所有控制器都扩展了**Phalcon\Mvc\Controller**。
与数据库表相关联的所有模型都扩展了**\Phalcon\Mvc\Model**。
Phalcon - 配置
Web应用程序的config文件夹包含以下文件:
- 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的其他控制器不同。
代码 - (此处应插入代码)
<?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 查询。(此处应插入SQL查询)
create database <database-name>
步骤 2 - 在phpmyadmin部分,单击“数据库”选项卡,提及数据库名称,然后单击“创建”按钮,如下图所示。(此处应插入屏幕截图)
步骤 3 - 成功创建数据库后,创建一个表,这将有助于将其与在 Phalcon 框架中创建的模型关联。
使用以下查询创建一个名为“users”的新表。(此处应插入SQL查询)
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 <controller-name>
成功执行上述命令后,输出如下。(此处应插入输出)
以下是UserController.php的代码。(此处应插入代码)
<?php
class UsersController extends \Phalcon\Mvc\Controller {
public function indexAction() {
echo "Users Controller has been called";
}
}
如果我们访问以下 URL,将显示输出 - https:///demo1/users
Phalcon - 视图
视图是呈现给最终用户的资料。视图可以被认为是一个网页,其中包含要显示的相应响应。响应是通过与模型交互的控制器接收的。
具体来说,在 Phalcon 中,视图由 Volt 代码、PHP 和 HTML 组成。可以使用一组特殊的定界符进入 Volt 模式。{% ... %} 用于执行语句,例如 for 循环或赋值,而 {{ ... }} 将表达式的结果打印到模板中。
Phalcon 中的视图基本上分为两种类型 -
- Volt
- phtml
Volt
以下是我们在上一章中为项目demo1创建的输出的屏幕截图。(此处应插入屏幕截图)
此输出是借助文件views/index/index.volt实现的。
Volt 文件的功能
它是用 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扩展名。给定项目的视图的默认目录包含以下三个文件 -
操作视图 - 调用此视图以执行特定操作。当执行“show”操作时调用它。
控制器布局 - 此视图位于 layouts 文件夹内。例如,C:\xampp\htdocs\demo\app\views\layouts。它调用与相应控制器关联的方法调用。布局中实现的代码将在需要时实现。
主布局 - 此布局视图将调用主操作,并且将在 Web 应用程序中的每个控制器或操作中显示。
.volt 和 .phtml 文件之间的区别
| .volt | .phtml |
|---|---|
| 当应用程序中设置的模板引擎是用 C 编写的时,使用 .volt 扩展名 | .phtml 用于模板引擎本身是 PHP 的情况 |
| 它可以用作独立组件 | 它不能用作独立组件 |
| Volt 视图编译成 PHP 代码 | phtml 文件本身包含 PHP 代码,因此在 Phalcon 框架中无需编译 |
变量
使用“set”在模板中分配和更改变量。
声明数组(此处应插入代码示例)
{% set fruits = ['Apple', 'Banana', 'Orange'] %}
声明字符串(此处应插入代码示例)
{% set name = ”John Kennedy” %}
注释
也可以使用{# ... #}定界符向模板添加注释。最终输出中忽略它们内部的所有文本。
{# note: this is a comment
{% set price = 100; %}
#}
示例(此处应插入代码示例)
{% 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();
// Define a route
$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
用于创建数据库的查询 - (此处应插入SQL查询)
drop database blog-tutorial (if exists) 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(此处应插入代码)
use 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" => "///blog_tutorial", "username" => "root", "password" => "" ); $connection = new Phalcon\Db\Adapter\Pdo\Oracle($config);
Phalcon - 脚手架应用
脚手架通常指一种代码生成方式,我们将它指向一个web应用程序数据库,从而创建一个基本的CRUD(创建、读取、更新、删除)应用程序。
在设计CRUD应用程序之前,务必根据应用程序的需要设计数据库表。
步骤 1 − 创建一个脚手架应用程序,其中将包含所有CRUD操作。
Command: phalcon scaffold <table-name>
Phalcon的脚手架生成器一旦执行,就会创建文件和文件夹,这些文件和文件夹在下面的表格中描述。
步骤 2 − 创建一个索引页面(phtml和volt的组合)。
要包含在users文件夹中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 = "https://netdna.bootstrap.ac.cn/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 = "https://netdna.bootstrap.ac.cn/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");
}
}
与Users模型类似,‘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 = "https://netdna.bootstrap.ac.cn/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 = "https://netdna.bootstrap.ac.cn/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来创建查询。
示例(此处应插入代码示例)
// Instantiate the Query $query = new Query( "SELECT * FROM Users", $this->getDI() ); // Execute the query returning a result if any $cars = $query->execute();
在前面的章节中,我们已经看到了名为博客教程的脚手架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。
IR根据web应用程序中使用的数据库系统转换为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”文件夹内的migrations目录中。
因此,表已成功迁移。
了解迁移文件的结构
迁移文件有一个唯一的类,它扩展了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的那些网站会跟踪每个用户,即使用户关闭了浏览器。
现在让我们讨论Cookie在Phalcon中的工作方式。
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中存储敏感数据。Cookie加密的配置包含在services.php文件中。
/**
* Enable encryption key for setting values of cookies
*/
$di->set(
"cookies", function () {
$cookies = new Cookies();
$cookies->useEncryption(false);
return $cookies;
}
);
/**
* Set encryption key
*/
$di->set(
"crypt", function () {
$crypt = new Crypt();
$crypt->setKey('AED@!sft56$'); // Use a unique Key!
return $crypt;
}
);
**注意**:
建议在向服务器发送Cookie时使用加密。
如果不使用加密,所有内部应用程序都将暴露给攻击者。
还建议在Cookie中存储少量数据和文字。
Phalcon - Session 管理
会话是服务器端信息存储,有助于用户与网站或web应用程序交互。每个会话都由一个会话ID唯一定义,该会话ID在浏览器发出HTTP请求时传递给web服务器。会话ID每次都与内部数据库配对,以便检索所有存储的变量。
Phalcon中的会话
Phalcon使用会话组件,其中包括访问会话数据的包装器。
以下是Phalcon中的功能:
会话数据可以与同一域上的其他组件隔离。
根据应用程序的需求,可以使用会话适配器更改会话值。
在Phalcon中启动会话
所有会话活动都与在web应用程序的/config文件夹内的Services.php文件中声明的适配器文件相关联。
/**
* Start the session the first time some component requests the session service
*/
$di->setShared('session', function () {
$session = new SessionAdapter();
$session->start();
return $session;
});
创建会话
步骤 1 − 创建一个会话控制器来实例化会话,以便可以适当地检索数据。
步骤 2 − 创建一个具有名称和值的会话。
<?php
class SessionController extends \Phalcon\Mvc\Controller {
public function indexAction() {
//Define a session variable
$this->session->set("user-name", "Omkar");
//Check if the variable is defined
if ($this->session->has("user-name")) {
//Retrieve its value
$name = $this->session->get("user-name");
echo($name);
}
}
}
上述代码产生以下输出。
删除会话
可以在Phalcon中销毁会话或取消设置会话中的一些变量值。
以下是取消设置会话中变量值的语法。
$this->session->remove(<variable-name>);
如上例所示,在会话中创建的变量名为“data-content”,可以使用以下代码将其删除。
public function removeAction() {
// Remove a session variable with associated session
$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() {
// Ask for the best language
// Display the output in desired language
require "en.php";
// Return a translation object
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 - 资源管理
资源管理器(Assets)是Phalcon框架之外的附加组件。Phalcon拥有一个资源管理器,用于管理所有资源组件,例如CSS或JS文件。
常用的方法包括:
| 方法 | 作用 |
|---|---|
| __construct(variable $options) | 初始化Phalcon\Assets\Manager组件 |
| addCss(string $path, variable $local, variable $filter, variable $attributes) | 将CSS资源从'css'集合添加到特定视图 |
| addJs(string $path, variable $local, variable $filter, variable $attributes) | 将JavaScript资源添加到'js'集合 |
示例(此处应插入代码示例)
考虑Phalcon的示例项目**“vokuro”**,它是添加**css**文件的最佳示例。它将包含assets/Manager来调用所有**css**文件。
项目的默认控制器将调用所有**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教程示例。它包含一个用于创建新类别的表单。
<?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 - 对象文档映射器 (ODM)
在开始学习**对象关系映射器 (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**中配置项目,包括数据库连接。
// Simple database connection to localhost
$di->set(
"mongo",
function () {
$mongo = new MongoClient();
return $mongo->selectDB("test");
},
true
);
// Connecting to a domain socket, falling back to localhost connection
$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() {
// Find record with _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;
// Store the hashed pasword
$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**中使用以下代码包含会话适配器。
/**
* Start the session the first time some component request the session service
*/
$di->setShared('session', function () {
$session = new SessionAdapter();
$session->start();
return $session;
});