日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

php框架费尔康,GitHub - majixian/study-phalcon: phalcon(费尔康)框架学习笔记

發布時間:2025/3/15 php 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php框架费尔康,GitHub - majixian/study-phalcon: phalcon(费尔康)框架学习笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

phalcon(費爾康)框架學習筆記

以實例程序invo為例(invo程序放在網站根目錄下的invo文件夾里,推薦php版本>=5.4)

環境不支持偽靜態網址時的配置

第一步:

在app\config\config.ini文件中的[application]節點內修改baseUri參數值為/invo/index.php/或/invo/index.php?_url=/,并增加一個參數staticBaseUri,值設為/invo/。

例如:

;支持非偽靜態網址

baseUri = "/invo/index.php?_url=/"

;靜態資源文件網址

staticBaseUri = /invo/

如果將baseUri設置為/invo/index.php/的話,需要在router服務中作如下設置,才能正常工作:

$di -> set('router', function () {

$router = new Router();

$router->setUriSource(Router::URI_SOURCE_SERVER_REQUEST_URI);//重要

return $router;

});

第二步:

在文件app\config\services.php中找到$di->set('url',所在位置,在其中的匿名函數內return語句前增加一行,輸入$url->setStaticBaseUri($config->application->staticBaseUri);

這里使用的是phalcon v2.0.2,此版本在使用非偽靜態網址的過程中,發現存在一個bug:當在模板中使用$this->tag->linkTo('products/search?page=1')函數生成網址時,由于第一個參數中包含了問號,再加上配置文件中的baseUri中也包含問號,這樣生成的網址中就包含兩處問號,只能通過自己擴展Url類來修復了,下面是修復步驟。

在文件app\config\services.php中添加以下代碼:

/**

* 重寫Url,修復動態網址中關于問號的bug

*

* @author:S.W.H

* @E-mail:swh@admpub.com

* @update:2015/6/9

*/

class MyUrl extends UrlProvider{

static public $hasDynamicUrl=null;

public function get($uri=null, $args=null, $local=null){

if(self::$hasDynamicUrl && strpos($uri,'?')!==false){

$uri=str_replace('?','&',$uri);

}

return parent::get($uri, $args, $local);

}

}

并將代碼:

$url = new UrlProvider();

替換為:

$url = new \MyUrl();

\MyUrl::$hasDynamicUrl=strpos($config->application->baseUri,'?')!==false;

即可解決。

路由規則

添加路由規則:

use Phalcon\Mvc\Router;

// Create the router

$router = new Router();

//Define a route

$router->add(

"/admin/:controller/a/:action/:params",

array(

"controller" => 1, //匹配第一個占位符(/:controller)

"action" => 2, //匹配第二個占位符(/:action)

"params" => 3, //匹配第三個占位符(/:params)

)

);

支持的占位符有:

占位符

正則表達式

Usage

/:module

/([a-zA-Z0-9_-]+)

Matches a valid module name with alpha-numeric characters only

/:controller

/([a-zA-Z0-9_-]+)

Matches a valid controller name with alpha-numeric characters only

/:action

/([a-zA-Z0-9_]+)

Matches a valid action name with alpha-numeric characters only

/:params

(/.*)*

Matches a list of optional words separated by slashes. Use only this placeholder at the end of a route

/:namespace

/([a-zA-Z0-9_-]+)

Matches a single level namespace name

/:int

/([0-9]+)

Matches an integer parameter

Controller名稱是采用駝峰命名法(camel),這意味著“-”和“_”將會被刪除并將其后的一個字符大寫。

例如,some_controller 會被轉換為 SomeController。

指定參數名稱

方式一,在數組中指定:

$router->add(

"/news/([0-9]{4})/([0-9]{2})/([0-9]{2})/:params",

array(

"controller" => "posts",

"action" => "show",

"year" => 1, // ([0-9]{4})

"month" => 2, // ([0-9]{2})

"day"=> 3, // ([0-9]{2})

"params" => 4, // :params

)

);

在上面的例子中,路由沒有定義“controller”和“action”部分,而是被指定為“posts”和“show”,這樣,用戶將不知道控制器的真實請求路徑。

在controller中,這些被命名的參數可以用如下方式這樣訪問:

use Phalcon\Mvc\Controller;

class PostsController extends Controller{

public function indexAction(){

}

public function showAction(){

// Return "year" parameter

$year = $this->dispatcher->getParam("year");

// Return "month" parameter

$month = $this->dispatcher->getParam("month");

// Return "day" parameter

$day = $this->dispatcher->getParam("day");

}

}

方式二,在路由中指定:

$router->add(

"/documentation/{chapter}/{name}.{type:[a-z]+}",

array(

"controller" => "documentation",

"action" => "show"

)

);

看見了嗎?花括號中的chaper、name和type就是相對應的名稱了。

總結:路由中的匹配項,可以使用

占位符

正則表達式

帶命名的正則表達式(命名與正則表達式間用冒號“:”隔開,并整個用花括號括起來)

{命名}

指定名稱空間的例子:

$router->add("/login", array(

'namespace' => 'Backend\Controllers',

'controller' => 'login',

'action' => 'index'

));

鉤子事件

轉換某個參數的值:

//The action name allows dashes, an action can be: /products/new-ipod-nano-4-generation

$router->add('/products/{slug:[a-z\-]+}', array(

'controller' => 'products',

'action' => 'show'

))->convert('slug', function($slug) {

//Transform the slug removing the dashes

return str_replace('-', '', $slug);

});

除了convert方法之外,還支持:

匹配回調函數

->beforeMatch(function($uri, $route) {

//Check if the request was made with Ajax

if ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'xmlhttprequest') {

return false;

}

return true;

});//參數可以是匿名函數,也可以采用數組的方式指定某個對象的方法:array(new AjaxFilter(), 'check')

限制主機名

->setHostName('([a-z+]).company.com');

路由分組

use Phalcon\Mvc\Router;

use Phalcon\Mvc\Router\Group as RouterGroup;

$router = new Router();

//Create a group with a common module and controller

$blog = new RouterGroup(array(

'module' => 'blog',

'controller' => 'index'

));

//All the routes start with /blog

$blog->setPrefix('/blog');

//Add another route to the group

$blog->add('/edit/{id}', array(

'action' => 'edit'

));

//Add the group to the router

$router->mount($blog);

或者:

use Phalcon\Mvc\Router\Group as RouterGroup;

class BlogRoutes extends RouterGroup{

public function initialize(){

//Default paths

$this->setPaths(array(

'module' => 'blog',

'namespace' => 'Blog\Controllers'

));

//All the routes start with /blog

$this->setPrefix('/blog');

//Add another route to the group

$this->add('/edit/{id}', array(

'action' => 'edit'

));

}

}

Then mount the group in the router:

//Add the group to the router

$router->mount(new BlogRoutes());

路由命名

$route = $router->add("/posts/{year}/{title}", "Posts::show");

$route->setName("show-posts");

//或者這樣

$router->add("/posts/{year}/{title}", "Posts::show")->setName("show-posts");

然后,我們就可以根據命名來生成符合這條路由的網址了:

// returns /posts/2012/phalcon-1-0-released

echo $url->get(array(

"for" => "show-posts",//路由名稱

"year" => "2012",//參數year的值

"title" => "phalcon-1-0-released" //參數title的值

));

指定URI來源

use Phalcon\Mvc\Router;

...

$router->setUriSource(Router::URI_SOURCE_GET_URL); // use $_GET['_url'] (default)

$router->setUriSource(Router::URI_SOURCE_SERVER_REQUEST_URI); // use $_SERVER['REQUEST_URI'] (default)

限制HTTP請求方式

當您使用路由的add方法時,意味著不限制HTTP請求方式。

有時我們可以限制一個路由使用一個特定的方式來訪問,這在創建RESTful應用程序時將非常有用:

// This route only will be matched if the HTTP method is GET

$router->addGet("/products/edit/{id}", "Products::edit");

// This route only will be matched if the HTTP method is POST

$router->addPost("/products/save", "Products::save");

// This route will be matched if the HTTP method is POST or PUT

$router->add("/products/update")->via(array("POST", "PUT"));

限制http請求方式:$router->addGet()、$router->addPut()、$router->addPost()……

設置默認

可以為通用路徑中的 module, controller, action 定義默認值。當一個路由缺少其中任何一項時,路由器可以自動用默認值填充:

//Setting a specific default

$router->setDefaultModule('backend');

$router->setDefaultNamespace('Backend\Controllers');

$router->setDefaultController('index');

$router->setDefaultAction('index');

//Using an array

$router->setDefaults(array(

'controller' => 'index',

'action' => 'index'

));

匿名路由

此組件提供了一個與注解服務集成的變體。使用此策略可以在控制器中直接寫路由。

use Phalcon\Mvc\Router\Annotations as RouterAnnotations;

$di['router'] = function() {

//Use the annotations router

$router = new RouterAnnotations(false);

//Read the annotations from ProductsController if the uri starts with /api/products

$router->addResource('Products', '/api/products');

return $router;

};

可以按如下方式定義注解:

/**

* @RoutePrefix("/api/products")

*/

class ProductsController

{

/**

* @Get("/")

*/

public function indexAction() {}

/**

* @Get("/edit/{id:[0-9]+}", name="edit-robot")

*/

public function editAction($id) {}

/**

* @Route("/save", methods={"POST", "PUT"}, name="save-robot")

*/

public function saveAction() {}

/**

* @Route("/delete/{id:[0-9]+}", methods="DELETE",

* conversors={id="MyConversors::checkId"})

*/

public function deleteAction($id) {}

public function infoAction($id) {}

}

支持的注解有:

Name

Description

Usage

RoutePrefix

A prefix to be prepended to each route uri. This annotation must be placed at the class’ docblock

@RoutePrefix(“/api/products”)

Route

This annotation marks a method as a route. This annotation must be placed in a method docblock

@Route(“/api/products/show”)

Get

This annotation marks a method as a route restricting the HTTP method to GET

@Get(“/api/products/search”)

Post

This annotation marks a method as a route restricting the HTTP method to POST

@Post(“/api/products/save”)

Put

This annotation marks a method as a route restricting the HTTP method to PUT

@Put(“/api/products/save”)

Delete

This annotation marks a method as a route restricting the HTTP method to DELETE

@Delete(“/api/products/delete/{id}”)

Options

This annotation marks a method as a route restricting the HTTP method to OPTIONS

@Option(“/api/products/info”)

用注解添加路由時,支持以下參數:

Name

Description

Usage

methods

Define one or more HTTP method that route must meet with

@Route(“/api/products”, methods={“GET”, “POST”})

name

Define a name for the route

@Route(“/api/products”, name=”get-products”)

paths

An array of paths like the one passed to Phalcon\Mvc\Router::add

@Route(“/posts/{id}/{slug}”, paths={module=”backend”})

conversors

A hash of conversors to be applied to the parameters

@Route(“/posts/{id}/{slug}”, conversors={id=”MyConversor::getId”})

如果要將路由映射到模塊中的控制器,可以使用addModuleResource方法:

use Phalcon\Mvc\Router\Annotations as RouterAnnotations;

$di['router'] = function() {

//Use the annotations router

$router = new RouterAnnotations(false);

//Read the annotations from Backend\Controllers\ProductsController if the uri starts with /api/products

$router->addModuleResource('backend', 'Products', '/api/products');

return $router;

};

###路由執行事件

依次按以下順序執行:

dispatch:beforeDispatchLoop

開始循環匹配路由

dispatch:beforeDispatch

dispatch:beforeNotFoundAction

dispatch:beforeExecuteRoute

beforeExecuteRoute($dispatcher)

initialize() -> dispatch:afterInitialize

執行路由到的方法

dispatch:afterExecuteRoute

dispatch:afterDispatch

afterExecuteRoute($dispatcher)

結束循環匹配路由

dispatch:afterDispatchLoop

其中,以“dispatch:”開頭的均為eventManager中定義的事件名稱?!皒xx(...)”這種格式的均為控制器中的方法。

控制器命名

默認調用IndexController控制器中的indexAction方法。

控制器名稱需要加Controller后綴,動作名稱需要加Action后綴。

控制器的首字母要大寫且繼承自Phalcon\Mvc\Controller。

控制器的文件名稱與控制器全名完全相同并加擴展名“.php”。

視圖渲染

Phalcon\Mvc\View 默認采用PHP本身作為模板引擎,此時應該以.phtml作為視圖文件擴展名。

可以在控制器方法中使用$this->view->setVar("postId", $postId);來傳遞變量到視圖,然后在視圖中用php來使用此變量,比如:<?php echo $postId;?>,setVar方法也可以通過接收關鍵字索引數組來一次傳遞多個值(類似于smarty中assign的批量賦值)。

Phalcon\Mvc\View 支持視圖分層。

分層渲染

第一步、渲染模板:

視圖文件目錄/小寫的控制器名(不含后綴)/方法名(不含后綴).phtml

并保存結果。級別代號LEVEL_ACTION_VIEW。

可在此模板中通過調用<?php echo $this->getContent() ?>輸出控制器中的輸出內容(比如在控制器中使用echo輸出一些內容)。

第二步、渲染模板(如果有):

視圖文件目錄/layouts/小寫的控制器名(不含后綴).phtml

并保存結果。級別代號LEVEL_LAYOUT。

可在此模板中通過調用<?php echo $this->getContent() ?>輸出第一步的模板結果。

第三步、渲染模板(如果有):

視圖文件目錄/index.phtml

并保存結果。級別代號LEVEL_MAIN_LAYOUT。

同樣的,可在此模板中通過調用<?php echo $this->getContent() ?>輸出第二步的模板結果。

最后保存的結果就是視圖的最終結果。

可以在控制器方法中使用$this->view->setTemplateAfter('common');來在第三步之前插入一個渲染操作,比如這里渲染模板:視圖文件目錄/layouts/common.phtml

渲染級別控制

可以在控制器方法中使用$this->view->setRenderLevel(View::LEVEL_NO_RENDER);來關閉渲染,或者僅僅渲染某個級別$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);

也可以使用$this->view->disableLevel(View::LEVEL_MAIN_LAYOUT);來禁止某個級別的渲染。

可以用$this->view->pick('index/pick');選擇視圖:

如果pick方法接收到一個不包含“/”的字符串則僅僅設置LEVEL_ACTION_VIEW級視圖;如果包含“/”則同時還會把第一個“/”前面的部分作為LEVEL_LAYOUT級視圖,比如這里會使用“視圖文件目錄/layouts/index.phtml”文件

如果接收到一個數字索引數組,則會將編號為0的元素作為LEVEL_ACTION_VIEW級視圖,將編號為1的元素作為LEVEL_LAYOUT級視圖

關閉視圖

如果你的控制器不在視圖里產生(或沒有)任何輸出,你可以禁用視圖組件來避免不必要的處理:

$this->view->disable();

在模板中包含局部模板

<?php $this->partial('shared/login');?>

或者同時傳遞變量給局部模板,每一個索引最終會作為變量在局部模板中被賦值:

$this->partial('shared/login',array(

'var1'=>'val1',

'var2'=>'val2'

));

?>

緩存視圖

在控制器方法中的代碼例子:

//Check whether the cache with key "downloads" exists or has expired

if ($this->view->getCache()->exists('downloads')) {

//Query the latest downloads

$latest = Downloads::find(array(

'order' => 'created_at DESC'

));

$this->view->latest = $latest;

}

//Enable the cache with the same key "downloads"

$this->view->cache(array(

'service' => 'myCache',//使用自己的緩存服務,不設置時默認為viewCache

'lifetime' => 86400,//緩存時間

'key' => 'downloads'//緩存索引名

));

注冊緩存服務:

use Phalcon\Cache\Frontend\Output as OutputFrontend;

use Phalcon\Cache\Backend\Memcache as MemcacheBackend;

//Set the views cache service

$di->set('viewCache', function() {

//Cache data for one day by default

$frontCache = new OutputFrontend(array(

'lifetime' => 86400

));

//Memcached connection settings

$cache = new MemcacheBackend($frontCache, array(

'host' => 'localhost',

'port' => '11211'

));

return $cache;

});

其中“Phalcon\Cache\Frontend”中包含了對前臺數據的處理操作(比如數據格式編碼等);

“Phalcon\Cache\Backend”中包含了對各種后臺緩存引擎的操作。

使用模板引擎

在控制器方法中指定模板引擎:

// Using more than one template engine

$this->view->registerEngines(

array(

'.my-html' => 'MyTemplateAdapter',

'.phtml' => 'Phalcon\Mvc\View\Engine\Php'

)

);

方法Phalcon\Mvc\View::registerEngines()接受一個包含定義模板引擎數據的數組。每個引擎的鍵名是一個區別于其他引擎的拓展名。模板文件和特定的引擎關聯必須有這些擴展名。

Phalcon\Mvc\View::registerEngines()會按照相關模板引擎定義的順序來執行。如果Phalcon\Mvc\View發現視圖文件具有相同名稱但擴展名不同,它只會使用第一個。

在注冊view服務時全局指定模板引擎:

use Phalcon\Mvc\View;

//Setting up the view component

$di->set('view', function() {

$view = new View();

//A trailing directory separator is required

$view->setViewsDir('../app/views/');

$view->registerEngines(array(

'.my-html' ='MyTemplateAdapter' //元素值可以是類名、服務名或返回模板引擎對象的匿名函數

));

return $view;

}, true);

Volt 視圖最終會被編譯成純PHP代碼

Volt模板引擎語法

3種不同含義的起始標簽

{% ... %}包裹的標簽用于賦值或執行for循環、if條件判斷等語句

{{ ... }}包裹的標簽用于打印表達式的結果到模板

{# ... #}包裹注釋,前后標簽可以處于不同行

語法詳解

{{ post.title }}相當于$post->title;

{{ post.getTypes().name }}相當于$post->getTypes()->name;

{{ post['title'] }}相當于$post['title'];

{{ post.title|e }}使用過濾器,豎線左邊表達式的值將會作為過濾器的第一個參數;

{{ '%.2f'|format(post.price) }}相當于執行sprintf('%.2f', $post->price);

默認過濾器列表:

Filter

Description

e

Applies Phalcon\Escaper->escapeHtml to the value

escape

Applies Phalcon\Escaper->escapeHtml to the value

escape_css

Applies Phalcon\Escaper->escapeCss to the value

escape_js

Applies Phalcon\Escaper->escapeJs to the value

escape_attr

Applies Phalcon\Escaper->escapeHtmlAttr to the value

trim

Applies the trim PHP function to the value. Removing extra spaces

left_trim

Applies the ltrim PHP function to the value. Removing extra spaces

right_trim

Applies the rtrim PHP function to the value. Removing extra spaces

striptags

Applies the striptags PHP function to the value. Removing HTML tags

slashes

Applies the slashes PHP function to the value. Escaping values

stripslashes

Applies the stripslashes PHP function to the value. Removing escaped quotes

capitalize

Capitalizes a string by applying the ucwords PHP function to the value

lower

Change the case of a string to lowercase

upper

Change the case of a string to uppercase

length

Counts the string length or how many items are in an array or object

nl2br

Changes newlines \n by line breaks (
). Uses the PHP function nl2br

sort

Sorts an array using the PHP function asort

keys

Returns the array keys using array_keys

join

Joins the array parts using a separator join

format

Formats a string using sprintf.

json_encode

Converts a value into its JSON representation

json_decode

Converts a value from its JSON representation to a PHP representation

abs

Applies the abs PHP function to a value.

url_encode

Applies the urlencode PHP function to the value

default

Sets a default value in case that the evaluated expression is empty

(is not set or evaluates to a falsy value)

convert_encoding

Converts a string from one charset to another

for循環用法

基礎用法:

{% for robot in robots %}

{{ robot.name|e }}

{% endfor %}

嵌套循環:

{% for robot in robots %}

{% for part in robot.parts %}

Robot: {{ robot.name|e }} Part: {{ part.name|e }}

{% endfor %}

{% endfor %}

獲取索引值

{% set numbers = ['one': 1, 'two': 2, 'three': 3] %}

{% for name, value in numbers %}

Name: {{ name }} Value: {{ value }}

{% endfor %}

用if進行篩選

{% for value in numbers if value < 2 %}

Value: {{ value }}

{% endfor %}

{% for name, value in numbers if name != 'two' %}

Name: {{ name }} Value: {{ value }}

{% endfor %}

else、elsefor

{% for robot in robots %}

Robot: {{ robot.name|e }} Part: {{ part.name|e }}

{% else %}{# else也可以寫成elsefor #}

There are no robots to show

{% endfor %}

可以在for結構中使用{% break %}和{% continue %}來跳出和執行下一次循環

if條件判斷

基本用法

{% if robot.type == "cyborg" %}

{{ robot.name|e }}

{% endif %}

{% if robot.type == "cyborg" %}

{{ robot.name|e }}

{% else %}

{{ robot.name|e }} (not a cyborg)

{% endif %}

{% if robot.type == "cyborg" %}

Robot is a cyborg

{% elseif robot.type == "virtual" %}

Robot is virtual

{% elseif robot.type == "mechanical" %}

Robot is mechanical

{% endif %}

if中可以使用的內置變量:

Variable

Description

loop.index

The current iteration of the loop. (1 indexed)

loop.index0

The current iteration of the loop. (0 indexed)

loop.revindex

The number of iterations from the end of the loop (1 indexed)

loop.revindex0

The number of iterations from the end of the loop (0 indexed)

loop.first

True if in the first iteration.

loop.last

True if in the last iteration.

loop.length

The number of items to iterate

賦值

單個變量賦值:

{% set fruits = ['Apple', 'Banana', 'Orange'] %}

{% set name = robot.name %}

多個變量賦值:

{% set fruits = ['Apple', 'Banana', 'Orange'], name = robot.name, active = true %}

支持的字面值:

字面值

說明

“this is a string”

被單引號或雙引號括起來的內容作為字符串

100.25

帶小數部分的數字作為(double/float)

100

不帶小數的數字作為整數(integer)

false

靜態內容“false”作為布爾值中false

true

Constant “true” is the boolean true value

null

Constant “null” is the Null value

數組可以用中括號或花括號定義

{# Other simple array #}

{{ ['Apple', 1, 2.5, false, null] }}

{# Multi-Dimensional array #}

{{ [[1, 2], [3, 4], [5, 6]] }}

{# Hash-style array #}

{{ ['first': 1, 'second': 4/2, 'third': '3'] }}

{% set myArray = {'Apple', 'Banana', 'Orange'} %}

{% set myHash = {'first': 1, 'second': 4/2, 'third': '3'} %}

算術運算符和比較符與PHP語法中的一致,邏輯運算符為:or,and,not

if中的is測試操作

內置支持的測試:

Test

Description

defined

Checks if a variable is defined (isset)

empty

Checks if a variable is empty

even

Checks if a numeric value is even

odd

Checks if a numeric value is odd

numeric

Checks if value is numeric

scalar

Checks if value is scalar (not an array or object)

iterable

Checks if a value is iterable. Can be traversed by a “for” statement

divisibleby

Checks if a value is divisible by other value

sameas

Checks if a value is identical to other value

type

Checks if a value is of the specified type

{%- macro my_input(name, class="input-text") %}

{% return text_field(name, 'class': class) %}

{%- endmacro %}

{# Call the macro #}

{{ '

' ~ my_input('name') ~ '

' }}

{{ '

' ~ my_input('name', 'input-text') ~ '

' }}

由以上代碼可見,模板中字符串間連接符為~!

Method

Volt function

Phalcon\Tag::linkTo

link_to

Phalcon\Tag::textField

text_field

Phalcon\Tag::passwordField

password_field

Phalcon\Tag::hiddenField

hidden_field

Phalcon\Tag::fileField

file_field

Phalcon\Tag::checkField

check_field

Phalcon\Tag::radioField

radio_field

Phalcon\Tag::dateField

date_field

Phalcon\Tag::emailField

email_field

Phalcon\Tag::numberField

number_field

Phalcon\Tag::submitButton

submit_button

Phalcon\Tag::selectStatic

select_static

Phalcon\Tag::select

select

Phalcon\Tag::textArea

text_area

Phalcon\Tag::form

form

Phalcon\Tag::endForm

end_form

Phalcon\Tag::getTitle

get_title

Phalcon\Tag::stylesheetLink

stylesheet_link

Phalcon\Tag::javascriptInclude

javascript_include

Phalcon\Tag::image

image

Phalcon\Tag::friendlyTitle

friendly_title

函數

Name

Description

content

Includes the content produced in a previous rendering stage

get_content

Same as ‘content’

partial

Dynamically loads a partial view in the current template

super

Render the contents of the parent block

time

Calls the PHP function with the same name

date

Calls the PHP function with the same name

dump

Calls the PHP function ‘var_dump’

version

Returns the current version of the framework

constant

Reads a PHP constant

url

Generate a URL using the ‘url’ service

模板的繼承

父模板(templates/base.volt)

`{% block title %}默認標題{% endblock %}`

子模板

{% extends "templates/base.volt" %}

{% block title %}重新定義的標題{% endblock %}

父模板中塊(block)內的內容會被子模板中的同名塊中的內容替換,除非在子模板中不存在該塊的定義。

如果想要保留或引用父模板中某block的內容,可以在子模板的同名塊中使用`{{ super() }}`

新增模板函數

use Phalcon\Mvc\View\Engine\Volt;

$volt = new Volt($view, $di);

$compiler = $volt->getCompiler();

//This binds the function name 'shuffle' in Volt to the PHP function 'str_shuffle'

$compiler->addFunction('shuffle', 'str_shuffle');//第二個參數可以是函數名或匿名函數

新增過濾器

//This creates a filter 'hash' that uses the PHP function 'md5'

$compiler->addFilter('hash', 'md5');//第二個參數可以是函數名或匿名函數

緩存視圖片段

{% cache ("article-" ~ post.id) 3600 %}

{{ post.title }}

{{ post.content }}

{% endcache %}

可以在模板中直接通過服務名訪問通過DI注冊的服務。

在php模板中使用“$this->服務名”來訪問。

設計表單

模型

模型類的名稱使用表名稱且首字母大寫(如果表名稱含下劃線“_”,需要刪除下劃線并將原下劃線位置后的一個字符大寫),繼承于Phalcon\Mvc\Model。

例如,我們有數據表member_account,那么我們需要創建一個模型類MemberAccount。

模型類的文件名稱與模型類名稱一致。

數據庫操作方法

查找: find() findFirst()

$robots = Robots::find(array(

"type = 'virtual'",

"order" => "name",

"limit" => 100

));

foreach ($robots as $robot) {

echo $robot->name, "\n";

}

$robots = Robots::find(array(

"conditions" => "type = ?1",

"bind" => array(1 => "virtual") //綁定參數(數字占位符)

));

$robot = Robots::findFirst(array("type = 'virtual'", "order" => "name"));

echo "The first virtual robot name is ", $robot->name, "\n";

可用的查詢選項如下:

參數

描述

舉例

conditions

查詢操作的搜索條件。用于提取只有那些滿足指定條件的記錄。默認情況下 Phalcon\Mvc\Model 假定第一個參數就是查詢條件。

"conditions" => "name LIKE 'steve%'"

columns

只返回指定的字段,而不是模型所有的字段。 當用這個選項時,返回的是一個不完整的對象。

"columns" => "id, name"

bind

綁定與選項一起使用,通過替換占位符以及轉義字段值從而增加安全性。

"bind" => array("status" => "A", "type" => "some-time")

bindTypes

當綁定參數時,可以使用這個參數為綁定參數定義額外的類型限制從而更加增強安全性。

"bindTypes" => array(Column::BIND_TYPE_STR, Column::BIND_TYPE_INT)

order

用于結果排序。使用一個或者多個字段,逗號分隔。

"order" => "name DESC, status"

limit

限制查詢結果的數量在一定范圍內。

"limit" => 10 / "limit" => array("number" => 10, "offset" => 5)

group

從多條記錄中獲取數據并且根據一個或多個字段對結果進行分組。

"group" => "name, status"

for_update

通過這個選項, Phalcon\Mvc\Model 讀取最新的可用數據,并且為讀到的每條記錄設置獨占鎖。

"for_update" => true

shared_lock

通過這個選項, Phalcon\Mvc\Model 讀取最新的可用數據,并且為讀到的每條記錄設置共享鎖。

"shared_lock" => true

cache

緩存結果集,減少了連續訪問數據庫。

"cache" => array("lifetime" => 3600, "key" => "my-find-key")

hydration

Sets the hydration strategy to represent each returned record in the result

"hydration" => Resultset::HYDRATE_OBJECTS

如果你愿意,除了使用數組作為查詢參數外,還可以通過一種面向對象的方式來創建查詢(更多可用類方法詳見源碼phalcon/mvc/model/criteria.zep):

$robots = Robots::query()

->where("type = :type:")

->andWhere("year < 2000")

->bind(array("type" => "mechanical")) //綁定參數(字符串占位符)

->order("name")

->execute();

最后,還有一個 findFirstBy() 方法。這個方法擴展了前面提及的 “findFirst()” 方法。它允許您利用方法名中的屬性名稱,通過將要搜索的該字段的內容作為參數傳給它,來快速從一個表執行檢索操作。

的內容為首字母大寫的數據表字段名(如果字段名稱含下劃線“_”,需要刪除下劃線并將原下劃線位置后的一個字符大寫)。

例如,數據表字段名為user_name,可以采用findFirstByUserName('admpub')方法查詢。

添加: create() 或 save()

//Creating a new robot

$robot = new Robots();

$robot->type = 'mechanical';

$robot->name = 'Astro Boy';

$robot->year = 1952;

$robot->create();

//Passing an array to create

$robot = new Robots();

$robot->create(array(

'type' => 'mechanical',

'name' => 'Astroy Boy',

'year' => 1952

));

更新: update() 或 save()

//Updating a robot name

$robot = Robots::findFirst("id=100");

$robot->name = "Biomass";

$robot->update();

//Passing an array to update

$robot->create(array(

'name' => 'Biomass'

),array('name'));//第二個參數用于指定允許設置的字段的名稱,不指定的話則表示允許數據表內全部字段名稱的鍵。

如果傳入的數組的鍵與數據表字段名不一致,可以使用$robot->assign(, , )來賦值。例如:

$robot = new Robots();

$robot->assign(

array(

'name' ='Biomass'

),

array('name'=>'user_name'),

array('user_name')

);

$robot->create();

刪除: delete()

$robot = Robots::findFirst("id=100");

$robot->delete();

foreach (Robots::find("type = 'mechanical'") as $robot) {

$robot->delete();

}

運算:

count()

//How many robots are there?

$number = Robots::count();

echo "There are ", $number, "\n";

//How many mechanical robots are there?

$number = Robots::count("type='mechanical'");

echo "There are ", $number, " mechanical robots\n"

sum()

//How much are all robots?

$sum = Robots::sum(array('column' => 'price'));

echo "The total price of robots is ", $sum, "\n";

//How much are mechanical robots?

$sum = Robots::sum(array("type='mechanical'", 'column' => 'price'));

echo "The total price of mechanical robots is ", $sum, "\n";

average()

用法與sum類似

maximum()

用法與sum類似

minimum()

用法與sum類似

保存: save()

$robot = new Robots();

$robot->type = 'mechanical';

$robot->name = 'Astro Boy';

$robot->year = 1952;

if ($robot->save() == false) {

echo "Umh, We can't store robots right now ";

foreach ($robot->getMessages() as $message) {

echo $message;

}

} else {

echo "Great, a new robot was saved successfully!";

}

$robot = new Robots();

$robot->save(array('type'=>'mechanical'),array('type'));//參數分別為array data,array whiteList

指定數據返回類型

$findResult->setHydrateMode(Resultset::HYDRATE_ARRAYS);

可選的值有:Resultset::HYDRATE_ARRAYS、Resultset::HYDRATE_OBJECTS、Resultset::HYDRATE_RECORDS。

也可以這樣指定:

$robots = Robots::find(array(

'hydration' => Resultset::HYDRATE_ARRAYS

));

綁定參數

占位符

數字占位符在sql中的格式為“?數字”;

字符串占位符在sql中的格式為“:字符串:”。

參數類型

默認的參數類型為\Phalcon\Db\Column::BIND_PARAM_STR。

支持的參數類型:

Column::BIND_PARAM_NULL 綁定null類型

Column::BIND_PARAM_INT 綁定整數類型

Column::BIND_PARAM_STR 綁定字符串類型

Column::BIND_PARAM_BOOL 綁定bool值類型

Column::BIND_PARAM_DECIMAL 綁定小數類型

$robots = Robots::find(array(

"conditions" => "name = :name: AND type = ?1",

"bind" => array('name'=>'admpub',1 => 'virtual'),

"bindTypes" => array(Column::BIND_TYPE_STR, Column::BIND_TYPE_STR)

));

模型關聯

有四種關聯類型:1對1,1對多,多對1,多對多。關聯可以是單向或者雙向的,每個關聯可以是簡單的(一個1對1的模型)也可以是復雜的(1組模型)。

在Phalcon中,關聯必須定義在某個模型的initialize()方法。通過方法belongsTo(),hasOne(),hasMany()和hasManyToMany()來定義當前模型中字段到另一個模型中字段之間的關聯。上述每種方法都需要三個參數:本地字段,引用的模型,引用的字段。

方法的具體含義:

Method

Description

hasMany

Defines a 1-n relationship

hasOne

Defines a 1-1 relationship

belongsTo

Defines a n-1 relationship

hasManyToMany

Defines a n-n relationship

多對多必須關聯3個模型,并分別設置它們的關聯字段

use Phalcon\Mvc\Model;

class Robots extends Model

{

public $id;

public $name;

public function initialize()

{

$this->hasManyToMany(

"id",//當前模型中的字段

"RobotsParts",//關聯到的中間表模型

"robots_id", "parts_id",//分別為當前模型id與中間表相關聯的字段和中間表與第三張表關聯的字段,這兩個字段都在中間表內

"Parts",//第三張表模型名

"id"//第三張表中與中間表關聯的字段

);

}

}

對于使用名稱空間的情況下,可以設置別名,或在model類中使用以下方法,但是對于多對多的情況,對于第三張表由于無法設置別名,只能使用以下方法:

$this->getRelated('Robots\Parts');

驗證信息

Phalcon\Mvc\Model可以生成如下驗證類型信息:

Type

Description

PresenceOf

Generated when a field with a non-null attribute on the database is trying to insert/update a null value

ConstraintViolation

Generated when a field part of a virtual foreign key is trying to insert/update a value that doesn’t exist in the referenced model

InvalidValue

Generated when a validator failed because of an invalid value

InvalidCreateAttempt

Produced when a record is attempted to be created but it already exists

InvalidUpdateAttempt

Produced when a record is attempted to be updated but it doesn’t exist

###事件

Phalcon\Mvc\Model會根據各個操作依序各自執行如下事件:

操作

事件名

是否能終止執行?

說明

Inserting/Updating

beforeValidation

YES

Is executed before the fields are validated for not nulls/empty strings or foreign keys

Inserting

beforeValidationOnCreate

YES

Is executed before the fields are validated for not nulls/empty strings or foreign keys when an insertion operation is being made

Updating

beforeValidationOnUpdate

YES

Is executed before the fields are validated for not nulls/empty strings or foreign keys when an updating operation is being made

Inserting/Updating

onValidationFails

YES (already stopped)

Is executed after an integrity validator fails

Inserting

afterValidationOnCreate

YES

Is executed after the fields are validated for not nulls/empty strings or foreign keys when an insertion operation is being made

Updating

afterValidationOnUpdate

YES

Is executed after the fields are validated for not nulls/empty strings or foreign keys when an updating operation is being made

Inserting/Updating

afterValidation

YES

Is executed after the fields are validated for not nulls/empty strings or foreign keys

Inserting/Updating

beforeSave

YES

Runs before the required operation over the database system

Updating

beforeUpdate

YES

Runs before the required operation over the database system only when an updating operation is being made

Inserting

beforeCreate

YES

Runs before the required operation over the database system only when an inserting operation is being made

Updating

afterUpdate

NO

Runs after the required operation over the database system only when an updating operation is being made

Inserting

afterCreate

NO

Runs after the required operation over the database system only when an inserting operation is being made

Inserting/Updating

afterSave

NO

Runs after the required operation over the database system

驗證數據

use Phalcon\Mvc\Model;

use Phalcon\Mvc\Model\Validator\Uniqueness;

use Phalcon\Mvc\Model\Validator\InclusionIn;

class Robots extends \Phalcon\Mvc\Model

{

public function validation()

{

$this->validate(new InclusionIn(

array(

"field" => "type",

"domain" => array("Mechanical", "Virtual")

)

));

$this->validate(new Uniqueness(

array(

"field" => "name",

"message" => "The robot name must be unique"

)

));

return $this->validationHasFailed() != true;

}

}

Phalcon\Mvc\Model\Validator包含以下驗證:

Email

Exclusionin

Inclusionin

Numericality

PresenceOf

Regex

StringLength

Uniqueness

Url

字段注解策略

use Phalcon\Mvc\Model;

class Robots extends Model

{

/**

* @Primary

* @Identity

* @Column(type="integer", nullable=false)

*/

public $id;

/**

* @Column(type="string", length=70, nullable=false)

*/

public $name;

/**

* @Column(type="string", length=32, nullable=false)

*/

public $type;

/**

* @Column(type="integer", nullable=false)

*/

public $year;

}

支持如下注解:

Name

Description

Primary

Mark the field as part of the table’s primary key

Identity

The field is an auto_increment/serial column

Column

This marks an attribute as a mapped column

注解@Column支持如下參數:

Name

Description

type

The column’s type (string, integer, decimal, boolean)

length

The column’s length if any

nullable

Set whether the column accepts null values or not

PHQL

在執行操作之前必須要有相應的model文件存在。

創建 PHQL 查詢

方式一、直接通過創建Phalcon\Mvc\Model\Query類的實例來查詢:

use Phalcon\Mvc\Model\Query;

// Instantiate the Query

$query = new Query("SELECT * FROM Cars", $this->getDI());

// Execute the query returning a result if any

$cars = $query->execute();

方式二、在控制器或視圖中,通過modelsManager(模型管理器)來查詢:

//Executing a simple query

$query = $this->modelsManager->createQuery("SELECT * FROM Cars");

$cars = $query->execute();

//With bound parameters

$query = $this->modelsManager->createQuery("SELECT * FROM Cars WHERE name = :name:");

$cars = $query->execute(array('name' => 'Audi'));

也可以簡化的寫為:

//Executing a simple query

$cars = $this->modelsManager->executeQuery("SELECT * FROM Cars");

//Executing with bound parameters

$cars = $this->modelsManager->executeQuery("SELECT * FROM Cars WHERE name = :name:", array('name' => 'Audi'));

注意:FROM后面的那個不是表名稱而是模型類名稱,這與真正的SQL語句是不同的。由于是模型類名稱,所以也可以帶名稱空間。

executeQuery($phql)與Cars::find()的查詢結果是一樣的;

executeQuery($phql)->getFirst()與Cars::findFirst()結果一樣。

插入數據:

// Inserting using placeholders

$phql = "INSERT INTO Cars (name, brand_id, year, style) "

. "VALUES (:name:, :brand_id:, :year:, :style:)";

$status=$manager->executeQuery($sql,

array(

'name' => 'Lamborghini Espada',

'brand_id' => 7,

'year' => 1969,

'style' => 'Grand Tourer',

)

);

//Create a response

#$response = new Response();

//Check if the insertion was successful

if ($status->success() == true) {

//Change the HTTP status

#$response->setStatusCode(201, "Created");

#$robot->id = $status->getModel()->id;

#$response->setJsonContent(array('status' => 'OK', 'data' => $robot));

} else {

//Change the HTTP status

#$response->setStatusCode(409, "Conflict");

//Send errors to the client

$errors = array();

foreach ($status->getMessages() as $message) {

$errors[] = $message->getMessage();

}

#$response->setJsonContent(array('status' => 'ERROR', 'messages' => $errors));

}

更新、刪除數據與插入數據類似。

使用查詢構建器創建查詢

//Getting a whole set

$robots = $this->modelsManager->createBuilder()

->from('Robots')

->join('RobotsParts')

->orderBy('Robots.name')

->getQuery()

->execute();

//Getting the first row

$robots = $this->modelsManager->createBuilder()

->from('Robots')

->join('RobotsParts')

->orderBy('Robots.name')

->getQuery()

->getSingleResult();

綁定參數

//Passing parameters in the query construction

$robots = $this->modelsManager->createBuilder()

->from('Robots')

->where('name = :name:', array('name' => $name))

->andWhere('type = :type:', array('type' => $type))

->getQuery()

->execute();

//Passing parameters in query execution

$robots = $this->modelsManager->createBuilder()

->from('Robots')

->where('name = :name:')

->andWhere('type = :type:')

->getQuery()

->execute(array('name' => $name, 'type' => $type));

轉義保留字

將保留字用中括號括起來。例如:

$phql = "SELECT * FROM [Update]";

$result = $manager->executeQuery($phql);

$phql = "SELECT id, [Like] FROM Posts";

$result = $manager->executeQuery($phql);

其它

URL重定向

重定向用來在當前的處理中跳轉到其它的處理流:

// 此路由重定向到其它的路由

$app->post('/old/welcome', function () use ($app) {

$app->response->redirect("new/welcome")->sendHeaders();

});

$app->post('/new/welcome', function () use ($app) {

echo 'This is the new Welcome';

});

有以下跳轉方式:

//設置一個內部跳轉

$this->response->redirect( 'posts/index' );

// 外部跳轉url

$this->response->redirect( 'http://www.admpub.com/blog', true );

// 設置跳轉 http狀態

$this->resopnse->redirect( 'http://www.admpub.com/blog' , true , 301 );

重定向不會禁用視圖組件。因此,如果你想從一個controller/action重定向到另一個controller/acton上,視圖將正常顯示。當然,你也可以使用 $this->view->disable() 禁用視圖輸出。

存儲/獲取 Session數據

$this->session->set("session_name", "session_value");

$this->session->has("session-name");

$this->session->get("session-name");

$this->session->remove("session-name");

$this->session->destroy();

From 表單接收

//獲取$_POST['name'],第二個參數是過濾器,還可以傳遞第三個參數作為默認值,第四個參數為是否允許為空。

//如果第一個參數為null或不傳遞任何參數的話,返回$_POST,以下getXXX()方法類似。

$name= $this->request->getPost("name", "string");

//獲取$_GET['email']

$email=$this->request->getQuery("email", "email");

//獲取$_REQUEST['email']

$email=$this->request->get("email", "email");

還有 $this->request->getPut、$this->request->getServer等等。

要判斷某個鍵的元素是否存在只需要將這里的get換成has即可。

比如:hasQuery('email')、has('email')、hasPost('email')、hasPut('email')、hasServer('HTTP_REFERER')。

支持的過濾器有:

email

absint

int

int!

使用intval函數處理

string

float

float!

使用doubleval函數處理

alphanum

trim

striptags

lower

upper

request的更多方法請參考phalcon源代碼:phalcon/http/request.zep

從容器中獲取的服務的最簡單方式就是只用get方法,它將從容器中返回一個新的實例:

<?php $request = $di->get('request'); ?>

或者通過下面這種魔術方法的形式調用:

<?php $request = $di->getRequest(); ?>

處理Not-Found

當用戶訪問未定義的路由時, 微應用會試著執行 "Not-Found"處理器。

$app->notFound(function () use ($app) {

$app->response->setStatusCode(404, "Not Found")->sendHeaders();

echo 'This is crazy, but this page was not found!';

});

微應用

事件名

觸發

是否可中止操作?

before

應用請求處理之前執行,常用來控制應用的訪問權限

Yes

after

請求處理后執行,可以用來準備回復內容

No

finish

發送回復內容后執行, 可以用來執行清理工作

No

### REST API

[https://docs.phalconphp.com/zh/latest/reference/tutorial-rest.html](https://docs.phalconphp.com/zh/latest/reference/tutorial-rest.html)

使用 phalcon devtools

如果提醒無法找到類這樣的錯誤提示,需要在phalcon.php文件中添加以下代碼:

spl_autoload_register(function($className){

$classDir = __DIR__.'/scripts/';

$classFile = $classDir . str_replace('\\', '/', $className) . '.php';

if (file_exists($classFile)) require_once($classFile);

});

把所有文件復制到現有phalcon項目下新建的“devtools”文件夾中,并將其中的webtools.php復制到public文件夾下,并在public文件夾內新建文件webtools.config.php,內容為:

define('PTOOLSPATH',__DIR__.'/../devtools/');

define('PTOOLS_IP','127.0.0.1');

spl_autoload_register(function($className){

$classDir = PTOOLSPATH.'/scripts/';

$classFile = $classDir . str_replace('\\', '/', $className) . '.php';

if (file_exists($classFile)) require_once($classFile);

});

修改public文件夾下的webtools.php文件,將其中的require 'webtools.config.php';剪切到文件最開頭的<?php下一行 。

經過測試,該工具對PHP版本要求較高,我在PHP5.4下無法使用。

#End

總結

以上是生活随笔為你收集整理的php框架费尔康,GitHub - majixian/study-phalcon: phalcon(费尔康)框架学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。