輕巧易於使用的PHP框架。
DeJframework是一個簡單而最小的PHP MVC框架,重點是簡潔,簡單性和可理解性。它的語法主要是從Laravel啟發的。 DeJframework是由ATA Marzban開發的,用於學士學位的最終項目。
#安裝
composer install 。為了使框架知道請求時該怎麼辦,您應該在 /app/routes.php中為應用程序設置路由。它很容易完成。
路由由HTTP方法,URL和如果使用指定的URL指定的方法提出請求,該路由應執行。沒有設置路線就無法執行任何執行。您可以將關閉作為目的地:
[/app/routes.php]
Route:: set ( " GET " , " / " , function (){
return " Hello World! " ;
});如果您訪問您的網站在yoursite.com上,則此代碼將輸出“ Hello World”。
[/app/routes.php]
Route:: set ( " GET " , " /some/url " , function (){
return " This is some url! " ;
});此代碼將輸出“這是一些URL!”如果您訪問您的網站,請訪問您的網站。
[/app/routes.php]
Route:: set ( " POST " , " /do/something " , function (){
return " Here you should write your own code to do the things you want. " ;
});如果您使用郵政方法訪問yoursite.com/do/something,則將執行此代碼。 (來自表格或API調用)
您可以在關閉或控制器中返回字符串,對象,數組或視圖(稍後討論)。字符串將直接輸出,而對像或視圖將自動轉換為JSON和輸出,並且視圖將呈現為輸出。
在下一部分中,您將學習如何將路由連接到控制器而不是關閉。
在MVC模式中,應將應用程序邏輯放入控制器中被認為是最佳實踐。
[/app/controllers/YourController.php]
<?php
namespace app controllers;
class YourController extends dej mvc Controller
{
public static function yourAction ()
{
return " This is the right way to do it! " ;
}
}重要的是:正如您在上面的示例中看到的,對於PSR-0自動加載器的功能正常,在將任何類添加到應用程序中時,應遵循以下約定:
現在,讓我們繼續學習如何使控制器正常工作:
[/app/routes.php]
Route:: set ( " GET " , " / " , " YourController@YourAction " );當路由觸發器時,將執行指定控制器上的指定操作。
不斷實例化課程並將依賴性傳遞給他們可能會成為PHP開發中的重複任務。 dej App服務提供商的目標是使此過程盡可能乾燥。使用此服務提供商,您無需在每個文件中添加使用語句並通過依賴項。以此示例:
/**
* Without a Service Provider
* when you want to build a query
*/
use dej db Connection ;
$ connection = Connection:: getInstance ();
use dej db Query ;
$ query = new Query ( $ connection );
$ result = $ query -> select ()-> from ( ' someTable ' )-> getAll ();
return $ result ;每當您想使用查詢構建器時,都應重複這一點。現在,使用服務提供商:
use dej App ;
return App:: Query ()-> select ()-> from ( ' some_table ' );就是這樣!看看DEJ/app.php,以查看其工作原理。在應用程序類上調用了一個名為“查詢”的靜態方法。它實例化查詢類並將連接實例作為構造函數參數傳遞給其。蛋糕!
#request dejhttpRequest類使與請求的互動變得容易,請查看以下示例:
//check if request is ajax or not
$ result = App:: Request ()-> isAjax ();
//returns $_GET['name'];
$ result = App:: Request ()-> get ( ' name ' );
//returns $_POST['name'];
$ result = App:: Request ()-> post ( ' name ' );
//returns $_REQUEST;
$ result = App:: Request ()-> all (); #Response dejhttpResponse類使設置響應參數變得容易,如果要設置HTTP響應代碼或標題,則應在控制器中返迴響應,請查看以下示例:
class IndexController extends dej mvc Controller
{
public static function index ()
{
return App:: Response ()-> code ( 404 )-> header ( ' HTTP/1.1 404 Not Found ' );
}
}您可以輕鬆地重定向:
//in the controller
return App:: Response ()-> redirect ( ' /login ' );
//redirect with errors
App:: Response ()-> redirect ( ' / ' )-> withErrors ([ ' login ' => ' login unsuccessful! maybe password is wrong. ' ]);通過錯誤重定向會閃爍到會話的錯誤(稍後討論)。
配置:首先在/config.json中輸入數據庫配置。 DeJframework在三層體系結構中處理數據庫:
第1層 - 數據庫連接對象:這擴展了Singleton抽像類。這意味著它僅是實例化的一次,這是第一次被稱為。 DeJframework上的其他一些服務也是如此。為了防止每次要運行查詢時連接到數據庫的開銷。這是您可以使用它的方法:
//simple query
$ result = App:: Connection ()-> executeQuery ( " SELECT * FROM some_table " );
//NonQuery: a query that doesn't return rows, only the number of affected rows.
$ result = App:: Connection ()-> executeNonQuery ( " DELETE FROM some_table WHERE some_field = 'some_value' " );
//A Query using prepared statements, To protect against SQL Injection.
$ result = App:: Connection ()-> executeQuery ( " SELECT * FROM some_table WHERE some_field = ? " , [ " some_value " ]);
//A Query using prepared statements, To protect against SQL Injection. With Multiple Parameters.
$ result = App:: Connection ()-> executeQuery ( " SELECT * FROM some_table WHERE some_field = ? AND another_field = ? " , [ $ some_value , " another_value " ]);
//A Query using prepared statements, To protect against SQL Injection. With Named Parameters.
$ result = App:: Connection ()-> executeQuery ( " SELECT * FROM some_table WHERE some_field = :some_value_name
AND another_field = :another_value_name " ,
[ " :some_value_name " => $ some_value ,
" another_value_name " => " another_value " ]);您可以在任何地方執行此操作,只要您添加use dejApp; 。
第2層 - 查詢構建器:此類構建查詢並使用連接類使用安全準備的語句運行它們。它應該針對每個新查詢進行實例化,每次您鍵入App::Query()時,這是通過 /dej /app自動為您完成的,就像我們在Service Povider部分示例中看到的那樣。您可以使用方法鏈條使用它來構建查詢。看看以下示例:
$ result = App:: Query ()-> select ()-> from ( ' users ' )-> getAll ();
$ result = App:: Query ()-> select ()-> from ( ' users ' )-> getOne ();
$ result = App:: Query ()-> select ()-> from ( ' users ' )-> getJson ();
$ query = App:: Query ()-> select ()-> from ( ' users ' )-> getQuery ();如您所見,使用DEJ查詢構建器很簡單,請使用呼叫app :: query(),並且它會自動傳遞一個新的,依賴的注入Query類,然後您將其鏈接到它上的方法以添加您喜歡的條件,例如Select(),例如(),然後從(然後)使用get a in aw of the thes as a in a. get fet fet fet fet fet( getOne() getAll() ) getJson() )或構造的查詢( getQuery() )。結果以STDCLASS格式獲取,您可以輕鬆使用。值得注意的是,如果沒有在查詢末尾使用一種獲取方法,結果就不會被獲取。另外,您可以在多行上鍊接方法,例如,以多個步驟進行鏈接,以通過某種條件進行更改:
$ query = App:: Query ()-> select ();
if ( $ somecondition == true ) $ query -> from ( ' users ' );
else $ query -> from ( ' another_table ' );
$ result = $ query -> getAll ();在以下示例中,讓我們查看查詢構建器上可用的其他方法:
//All queries will be executed using prepared statements and parameters will be handled automatically.
//SELECT Queries:
$ result = App:: Query ()-> select ()-> from ( ' users ' )-> where ( ' id ' , ' = ' , ' 22 ' )-> getAll ();
//you can omit the operator and it uses '=' by default
$ result = App:: Query ()-> select ()-> from ( ' users ' )-> where ( ' id ' , ' 22 ' )-> getAll ();
$ result = App:: Query ()-> select ()-> from ( ' users ' )-> where ( ' city ' , ' = ' , ' Berlin ' )
-> andWhere ( ' age ' , ' > ' , ' 20 ' )-> getAll ();
$ result = App:: Query ()-> select ()-> from ( ' users ' )-> where ( ' city ' , ' = ' , ' Berlin ' )
-> orWhere ( ' city ' , ' = ' , ' Paris ' )-> getAll ();
$ result = App:: Query ()-> select ()-> from ( ' users ' )-> orderBy ( ' age ' , ' DESC ' )
-> limit ( 25 )
-> offset ( 50 )-> getAll ();
//INSERT Query:
$ affectedRows = App:: Query ()-> insertInto ( ' users ' )-> values ([ " username " => " jameshetfield " ,
" password " => " 19831983 " ,
" city " => " Downey " ])-> execute ();請注意,不返回結果的查詢必須使用php execute()執行,並且它將自動返回受影響的行的數量。
//UPDATE Query:
$ affectedRows = App:: Query ()-> update ( ' users ' )-> set ([ " age " => 53 ,
" band " => " Metallica " ])
-> where ( ' username ' , ' = ' , ' jameshetfield ' )-> execute ();
//DELETE Query:
$ affectedRows = App:: Query ()-> deleteFrom ( ' users ' )-> where ( ' username ' , ' = ' , ' someone ' )-> execute ();請注意,刪除或更新查詢可能會導致數據丟失,如果沒有提供的條款,作為安全措施,如果遇到這種情況,DEJFRAMEWORK將拋出異常。請手動使用連接類運行此類查詢。
第3層 - 對象相關映射: ORM將在下一部分中討論。
根據Wikipedia的說法:
對象關聯映射(ORM)...是一種編程技術,用於在面向對象的編程語言中不兼容類型系統之間轉換數據。這實際上創建了一個可以從編程語言中使用的“虛擬對像數據庫”。
由於DEJFRAMEWORK在MVC體系結構中起作用,因此數據持久性包含在MVC的模型組件中。模型與您應用程序中的實體有關,例如用戶,購買,產品等。它們需要保存並從數據庫中檢索。與大多數框架在面向對象的環境中運行一樣,關係數據庫以SQL語言和DEJFRAMEWORK工作。 PHP代碼中間的SQL代碼被認為不是最佳實踐。因此,DeJframework試圖將您與SQL代碼分為3個級別,其中2個在上一節中詳細闡述了,現在我們將看到如何使用模型:
class User extends dej mvc Model
{
protected static $ dbTable = " users " ;
//Format: ["db_field_name" => "modelPropertyName"]
protected static $ primaryKey = [ " id " => " id " ];
//Model properties
public $ username ;
public $ password ;
public $ city ;
.
.
.
} class User extends dej mvc Model
{
protected static $ dbTable = " users " ;
//Format: ["db_field_name" => "modelPropertyName"]
protected static $ dbFields = [ " username " => " username " ,
" password " => " password " ,
" city " => " city " ,
" id " => " id " ];
public $ username ;
public $ password ;
public $ city ;
.
.
.
}請注意, id屬性是在模型擴展的/dej/mvc/Model類中定義的。因此,如果您希望模型具有ID,則無需再次定義它。
class User extends dej mvc Model
{
protected static $ dbTable = " users " ;
protected static $ dbFields = [ " username " => " username " ,
" password " => " password " ,
" city " => " city " ,
" id " => " id " ];
//Exactly the same as the class name
protected static $ modelName = " User " ;
public $ username ;
public $ password ;
public $ city ;
.
.
.
}現在就是這樣,只要您已經正確設置了這些配置,則可以在模型上使用ORM方法。看看以下示例:
//Creating a new record
use app models User ;
$ user = new User ();
$ user -> username = " jameshetfield " ;
$ user -> password = " 13831383 " ;
$ user -> city = " Downey " ;
$ user -> create (); //Saved into the database.
//or you can set the properties in the constructor
$ user = new User ([
' username ' => ' jameshetfield ' ,
' password ' => ' 13831383 ' ,
' city ' => ' Downey '
]);
$ user -> create ();ORM使用下面的DEJ查詢構建器來生成必要的查詢。
請注意, create(),update()和delete()返回影響的行,您可以檢查一下操作是否成功。
//Finding a record by a field named 'id'
$ user = User:: findById ( 11 );
//changing it's properties
$ user -> password = " through_the_never " ;
$ user -> update (); //Updated in the database.
//deleting it.
$ user -> delete ();請注意,這些功能與記錄的主要鍵一起工作。
//Finding records by some condition.
$ users = User:: find ()-> where ( ' city ' , ' = ' , ' Sari ' )-> getAll (); //Returns an array of User objects.
//A more complex one
$ users = User:: find ()-> where ( ' city ' , ' = ' , ' Sari ' )-> andWhere ( ' age ' , ' > ' , 20 )-> orderBy ( ' age ' , ' ASC ' )
-> limit ( 25 )
-> offset ( 100 )-> getAll ();
//Don't forget the get*() method!
//Retrieveing all records
$ users = User:: getAll (); //doesn't need a getAll() at the end because it knows what to do.
//The method for deleting by condition is named 'wipe'
$ users = User:: wipe ()-> where ( ' status ' , ' = ' , ' banned ' )-> orWhere ( ' email_confirmation ' , ' = ' , ' 0 ' )-> execute ();
//counting all records
$ userCount = User:: countAll ();
//counting records that have a certain condition
$ userCount = User:: count ()-> where ( ' city ' , ' = ' , ' Sari ' )-> getInt (); //getInt() returns the count of the results as an Integer.DEJFRAMEWORK中的數據驗證由dejValidator類處理。您可以以各種方式使用它:
App::Validator()驗證服務,從而為您提供了它的singleton實例。它接受2個參數:要驗證的值。 (字符串,int,數組,對象)和一組規則以驗證數據相反。讓我們看看它的工作原理:
use dej App ;
//Validate a single value according to a set of rules seperated by "|".
$ result = App:: Validator ()-> validate ( " This is going to be validated " , " required|string|min:5|max:30 " );
//Validate an object or and array:
$ result = App:: Validator ()-> validate ( $ user , [ ' username ' => ' required|string|email|min:5|max:30 ' ,
' password ' => ' required|string|min:10|max:100 ' ],
' age ' => ' int|min:18|max:99 ' ); validate()方法返回數組。如果沒有驗證錯誤並且數據有效,則將是一個空數組。因此,您可以檢查數據是否有效使用empty() 。如果有任何驗證錯誤,您將在數組中看到它們。
//The rules have changed
$ errors = App:: Validator ()-> validate ( " This is going to be validated " , " required|string|email|min:5|max:10 " );
var_dump ( $ errors );這就是上述代碼將輸出的內容:
array
0 => 'This Field should be an email'
1 => 'This Field should be less than 10'
現在有一個對象:
$ errors = App:: Validator ()-> validate ( $ obj , [ ' email ' => ' required|string|email ' ,
' password ' => ' required|string ' ,
' age ' => ' int ' ]);
var_dump ( $ errors );輸出:
array (size=3)
'email' =>
array (size=1)
0 => string 'This Field should be an email'
'password' =>
array (size=2)
0 => string 'This Field is Required'
1 => string 'This Field should be more than 10'
'age' =>
array (size=1)
0 => string 'This Field should be a number'
如您所見,如果將對像或數組傳遞給驗證器,它將返回與關聯數組中的每個字段相關的錯誤,其中鍵是字段名稱,並且值是包含與該字段相關的錯誤的數組。
validate()方法來驗證請求參數(GET和POST參數)。 $ errors = App:: Request ()-> validate ([ ' email ' => ' required|string|email ' ,
' password ' => ' required|string|min:10|max:100 ' ]);
var_dump ( $ errors );訪問yoursite.local/?email=notanemail&password=123將導致:
array (size=2)
'email' =>
array (size=1)
0 => string 'This Field should be an email'
'password' =>
array (size=1)
0 => string 'This Field should be more than 10'
/app/models/User.php中的用戶模型: class User extends dej mvc Model
{
.
.
.
protected static $ validationRules = [ " username " => " required|string|min:5|max:20 " ,
" password " => " required|string|min:5|max:255 " ,
" city " => " string|max:10 " ];
.
.
.
}現在您可以驗證模型的實例:
$ user = User:: getById ( 11 );
$ errors = $ user -> validate (); //returns errors in array like the previous examples.
$ isValid = $ user -> isValid (); //returns true or false當您有錯誤時,您可以將其傳遞到視圖以顯示,或將其重定向到其中的某個地方:
//in the controller
$ errors = $ user -> validate ();
if (! empty ( $ errors )) return App:: Response ()-> redirect ( ' / ' )-> withErrors ( $ errors );您在上一個示例中看到的驗證消息是默認消息,如果您想更改它們,或者以自己的語言有驗證消息怎麼辦?看/app/locale/en/validation/messages.php :
return [
" required " => " This Field is Required " ,
" string " => " This Field should be an string " ,
" int " => " This Field should be a number " ,
" min " => " This Field should be more than %s " ,
" max " => " This Field should be less than %s " ,
" email " => " This Field should be an email " ,
];您可以看到鍵的對應於驗證類型,並且值是驗證消息。變量包含在“ S”的消息中。在/app/locale中,您可以為自己選擇的語言和該目錄中創建自己的目錄,並具有帶有變量的驗證消息。
您可以在/config.json中設置默認場所。
您可以通過App::Config()->locale = 'your_locale';
為了使用PHP會話,DeJframework提供dejSession類。以下是有關如何使用它的一些示例:
//to set session variables
App:: Session ()-> save ([
' key1 ' => ' value1 ' ,
' key2 ' => ' value2 '
]);
//to get session variables
$ value1 = App:: Session ()-> get ( ' key1 ' );
//to regenerate session id
App:: session ()-> regenerateId ();
//get all session variables as associative array
$ wholeSession = App:: session ()-> all ();
//destroy the session
App:: session ()-> destroy ();
//delete a variable
App:: session ()-> delete ( ' key1 ' );
//see if variable is set
$ trueOrFalse = App:: session ()-> isSaved ( ' key1 ' );如果您希望僅在下一個請求中可用會話變量,例如某個錯誤消息,則可以將其刷新到這樣的會話:
App:: session ()-> flash ([ ' message ' => ' Registered Successfully! ' ]);並在下一個請求中檢索它:
$ message = App:: session ()-> getFlash ( ' message ' );請注意,閃存消息僅在下一個請求中可用,只有->getFlash() 。
您可以將會話設置為自上次訪問會話以來定義的時間後到期:
App:: Session ()-> save ([ ' key ' => ' value ' ]);
App:: Session ()-> lifeTime ( 60 ); //session will expire after 60 seconds since last access to the session. (last use of App::Session())有時,您可能希望您的應用程序記住下一個請求的模型實例。例如,您希望您的應用記住登錄的用戶,或者用戶擁有的購物車或其他任何用戶。如果您在會話中存儲了所需的模型的主要鍵,並在每個請求中運行查詢以檢索它,則可能會變得乏味。 DeJframework通過為您提供可以在模型中使用的特徵來解決此問題。看看:
class ShoppingCart extends dej mvc Model
{
use dej traits IsStateful;
.
.
.
}現在,您在模型中有更多方法可用:
//suppose you want to create a shopping cart for a guest user and add a product to it:
$ cart = new ShoppingCart ();
$ cart -> addProduct ( 2389 );
$ cart -> create (); //stored in the db
//if you want to save it to the session get it easily in the next request
$ cart -> remember ( ' guest_shopping_cart ' ); //provide a key to remember it by this key.現在在下一個請求中:
if (ShoppingCart:: isRemembered ( ' guest_shopping_cart ' )) //see if theres any cart in the session
$ cart = ShoppingCart:: retrieve ( ' users_shopping_cart ' ); //get's fresh data from the db
if (ShoppingCart:: hasChanged ( ' guest_shopping_cart ' ))
{
//checks if the cart in the database has changed **since you saved the cart in the session**.
doSomeThing ();
}
ShoppingCart:: forget ( ' guest_shopping_cart ' ); //forgets the cart.要將數據顯示給用戶,您需要一個用戶界面。在網絡中,大多數情況下,這意味著HTML標記。在MVC中,必須將邏輯與UI分開,因此您將HTML放置在視圖中,並且僅在其中包含演示文稿邏輯,例如echo或將數組放入``foreach''中以迭代其上。要創建一個視圖,您應該:
/app/views中創建您的視圖文件。默認情況下包含一個視圖: index.phtml <!DOCTYPE html >
< html >
< head >
< title > < ?= $data- > user- > username ? > 's profile </ title >
</ head >
< body >
< h2 > View < ?= $data- > user- > username ? > 's Profile </ h2 >
< p > Username: < ?= $data- > user- > username ? > </ p >
< p > Password: < ?= $data- > user- > password ? > </ p >
< p > City: < ?= $data- > user- > city ? > </ p >
</ body >
</ html > class IndexController extends dej mvc Controller
{
public static function index()
{
$ user = User:: find ()-> where ( ' username ' , ' = ' , ' jameshetfield ' )-> getOne ();
return App:: View ( ' user ' , [ ' user ' => $ user ]); //the first argument is the view name,
the second one is the data you want to pass to
the view, in this example, a variable called ' user '
will be available in the user.phtml view
which contains the instance of user we fetched.
Piece of cake!
}
}您也可以提供錯誤消息:
//in the controller
return App:: View ( ' user ' )-> withErrors ([ ' authorization ' => ' You are not allowed to view this user. ' ]);該框架將使視圖輸出,結果將是:
<!DOCTYPE html >
< html >
< head >
< title > jameshetfield's profile </ title >
</ head >
< body >
<!-- access the errors like this: -->
< span class =" error " > < ?= $this- > errors('authorization') ? > </ span >
< h2 > View jameshetfield's Profile </ h2 >
< p > Username: jameshetfield </ p >
< p > Password: 13831383 </ p >
< p > City: Downey </ p >
</ body >
</ html >現在讓我們看看另一個示例,如果我們要創建所有用戶的表怎麼辦?編輯您的視圖:
<!DOCTYPE html >
< html >
< head >
< title > All Users </ title >
</ head >
< body >
< table >
< tr >
< th > username </ th >
< th > password </ th >
< th > city </ th >
</ tr >
< ?php foreach ($data- > users as $user): ? >
< tr >
< th > < ?= $user- > username ? > </ th >
< th > < ?= $user- > password ? > </ th >
< th > < ?= $user- > city ? > </ th >
</ tr >
< ?php endforeach; ? >
</ table >
</ body >
</ html >然後您的控制器:
class IndexController extends dej mvc Controller
{
public static function index ()
{
$ users = User:: getAll ();
return App:: View ( ' user ' , [ ' users ' => $ users ]);
}
}並親自看看結果!
您可以在其他視圖中創建查看部分並將其粘貼(包括):
[/app/views/partials/header.phtml]
<!--begin header-->
<!DOCTYPE html >
< html >
< head >
< meta charset =" UTF-8 " >
< title > < ?= $data- > title ? > </ title >
</ head >
< body >
<!--end header-->並將其粘貼到index.phtml :
[/app/views/index.phtml]
< ?php $this- > paste('partials/header'); ? >
< h2 > < ?= $data- > message ? > </ h2 >
.
.
.
</ html >身份驗證是與應用程序有關的問題。它在每個應用程序中都可能非常不同,因此DeJframework不會在框架本身中實現它,相反,您將為您提供基本的用戶模型,auth路由和控制器邏輯,使身份驗證發生並且您可以自由更改或實現自己的解決方案,或實現自己的解決方案,在框架中實現的IsStateful方案在用戶模型中$user->remember() 。您唯一需要做的就是在config.json中設置'default_auth_model' ,以便能夠使用IsStateful性狀使用App::Request->user() to ::retrieve()從會話中的用戶使用。
查看框架中提供的控制器,模型和視圖,以了解其工作原理。並隨心所欲地更改/改進/刪除它。
注意:要使用戶模型正常工作,您需要使用2個字段創建一個名為users的表:
TABLE: users
FIELD TYPE
id int, autoincrement
username varchar
password varchar(255) //password hashing system requires 255