klein.php هو جهاز توجيه سريع ومرن لـ PHP 5.3+
php composer.phar require klein/klein
require 'vendor/autoload.php';
مرحبا بالعالم - مثال إلزامي مرحبا بالعالم
<?php
require_once __DIR__ . ' /vendor/autoload.php ' ;
$ klein = new Klein Klein ();
$ klein -> respond ( ' GET ' , ' /hello-world ' , function () {
return ' Hello World! ' ;
});
$ klein -> dispatch ();
مثال 1 - الرد على كافة الطلبات
$ klein -> respond ( function () {
return ' All the things ' ;
});
المثال 2 - المعلمات المسماة
$ klein -> respond ( ' /[:name] ' , function ( $ request ) {
return ' Hello ' . $ request -> name ;
});
مثال 3 - مريح جدًا
$ klein -> respond ( ' GET ' , ' /posts ' , $ callback );
$ klein -> respond ( ' POST ' , ' /posts ' , $ callback );
$ klein -> respond ( ' PUT ' , ' /posts/[i:id] ' , $ callback );
$ klein -> respond ( ' DELETE ' , ' /posts/[i:id] ' , $ callback );
$ klein -> respond ( ' OPTIONS ' , null , $ callback );
// To match multiple request methods:
$ klein -> respond ( array ( ' POST ' , ' GET ' ), $ route , $ callback );
// Or you might want to handle the requests in the same place
$ klein -> respond ( ' /posts/[create|edit:action]?/[i:id]? ' , function ( $ request , $ response ) {
switch ( $ request -> action ) {
//
}
});
مثال 4 - إرسال الكائنات / الملفات
$ klein ->respond( function ( $ request , $ response , $ service ) {
$ service -> xml = function ( $ object ) {
// Custom xml output function
}
$ service -> csv = function ( $ object ) {
// Custom csv output function
}
});
$ klein -> respond ( ' /report.[xml|csv|json:format]? ' , function ( $ request , $ response , $ service ) {
// Get the format or fallback to JSON as the default
$ send = $ request -> param ( ' format ' , ' json ' );
$ response -> $ send ( $ report );
});
$ klein -> respond ( ' /report/latest ' , function ( $ request , $ response , $ service ) {
$ response -> file ( ' /tmp/cached_report.zip ' );
});
مثال 5 - كل ذلك معًا
$ klein -> respond ( function ( $ request , $ response , $ service , $ app ) use ( $ klein ) {
// Handle exceptions => flash the message and redirect to the referrer
$ klein -> onError ( function ( $ klein , $ err_msg ) {
$ klein -> service ()-> flash ( $ err_msg );
$ klein -> service ()-> back ();
});
// The fourth parameter can be used to share scope and global objects
$ app -> db = new PDO (...);
// $app also can store lazy services, e.g. if you don't want to
// instantiate a database connection on every response
$ app -> register ( ' db ' , function () {
return new PDO (...);
});
});
$ klein -> respond ( ' POST ' , ' /users/[i:id]/edit ' , function ( $ request , $ response , $ service , $ app ) {
// Quickly validate input parameters
$ service -> validateParam ( ' username ' , ' Please enter a valid username ' )-> isLen ( 5 , 64 )-> isChars ( ' a-zA-Z0-9- ' );
$ service -> validateParam ( ' password ' )-> notNull ();
$ app -> db -> query (...); // etc.
// Add view properties and helper methods
$ service -> title = ' foo ' ;
$ service -> escape = function ( $ str ) {
return htmlentities ( $ str ); // Assign view helpers
};
$ service -> render ( ' myview.phtml ' );
});
// myview.phtml:
<title> <?php echo $ this -> escape ( $ this -> title ) ?> </title>
$ klein -> with ( ' /users ' , function () use ( $ klein ) {
$ klein -> respond ( ' GET ' , ' /? ' , function ( $ request , $ response ) {
// Show all users
});
$ klein -> respond ( ' GET ' , ' /[:id] ' , function ( $ request , $ response ) {
// Show a single user
});
});
foreach ( array ( ' projects ' , ' posts ' ) as $ controller ) {
// Include all routes defined in a file under a given namespace
$ klein -> with ( " / $ controller " , " controllers/ $ controller .php " );
}
يتم تشغيل الملفات المضمنة في نطاق Klein ( $klein
) بحيث يمكن الوصول إلى جميع أساليب/خصائص Klein باستخدام $this
ملف مثال لـ: "controllers/projects.php"
// Routes to "/projects/?"
$ this -> respond ( ' GET ' , ' /? ' , function ( $ request , $ response ) {
// Show all projects
});
يمكن تخزين الخدمات بتكاسل ، مما يعني أنه يتم إنشاء مثيل لها فقط عند الاستخدام الأول.
<?php
$ klein -> respond ( function ( $ request , $ response , $ service , $ app ) {
$ app -> register ( ' lazyDb ' , function () {
$ db = new stdClass ();
$ db -> name = ' foo ' ;
return $ db ;
});
});
//Later
$ klein -> respond ( ' GET ' , ' /posts ' , function ( $ request , $ response , $ service , $ app ) {
// $db is initialised on first request
// all subsequent calls will use the same instance
return $ app -> lazyDb -> name ;
});
لإضافة مدقق مخصص، استخدم addValidator($method, $callback)
$ service -> addValidator ( ' hex ' , function ( $ str ) {
return preg_match ( ' /^[0-9a-f]++$/i ' , $ str );
});
يمكنك التحقق من صحة المعلمات باستخدام is<$method>()
أو not<$method>()
، على سبيل المثال
$ service -> validateParam ( ' key ' )-> isHex ();
أو يمكنك التحقق من صحة أي سلسلة باستخدام نفس التدفق.
$ service -> validate ( $ username )-> isLen ( 4 , 16 );
طرق التحقق من الصحة قابلة للتسلسل، ويمكن تحديد رسالة استثناء مخصصة في حالة فشل التحقق من الصحة
$ service -> validateParam ( ' key ' , ' The key was invalid ' )-> isHex ()-> isLen ( 32 );
[ نوع_المطابقة : اسم_المعلمة ]
بعض الأمثلة
* // Match all request URIs
[i] // Match an integer
[i:id] // Match an integer as 'id'
[a:action] // Match alphanumeric characters as 'action'
[h:key] // Match hexadecimal characters as 'key'
[:action] // Match anything up to the next / or end of the URI as 'action'
[create|edit:action] // Match either 'create' or 'edit' as 'action'
[*] // Catch all (lazy)
[*:trailing] // Catch all as 'trailing' (lazy)
[**:trailing] // Catch all (possessive - will match the rest of the URI)
.[:format]? // Match an optional parameter 'format' - a / or . before the block is also optional
بعض الأمثلة الأكثر تعقيدًا
/posts/[*:title][i:id] // Matches "/posts/this-is-a-title-123"
/output.[xml|json:format]? // Matches "/output", "output.xml", "output.json"
/[:controller]?/[:action]? // Matches the typical /controller/action format
ملاحظة - يتم استدعاء جميع المسارات التي تطابق URI للطلب - وهذا يسمح لك بدمج المنطق الشرطي المعقد مثل مصادقة المستخدم أو عرض التخطيطات. على سبيل المثال، كمثال أساسي، سوف يقوم التعليمة البرمجية التالية بتغطية المسارات الأخرى برأس وتذييل
$ klein -> respond ( ' * ' , function ( $ request , $ response , $ service ) { $ service -> render ( ' header.phtml ' ); });
//other routes
$ klein -> respond ( ' * ' , function ( $ request , $ response , $ service ) { $ service -> render ( ' footer.phtml ' ); });
تتطابق المسارات تلقائيًا مع URI للطلب بالكامل. إذا كنت تريد مطابقة جزء فقط من URI للطلب أو استخدام تعبير عادي مخصص، فاستخدم عامل التشغيل @
. إذا كنت بحاجة إلى إلغاء المسار، استخدم !
المشغل
// Match all requests that end with '.json' or '.csv'
$ klein ->respond( ' @.(json|csv)$ ' , ...
// Match all requests that _don't_ start with /admin
$ klein ->respond( ' !@^/admin/ ' , ...
يمكنك إرسال خصائص أو مساعدين إلى العرض عن طريق تعيينهم لكائن $service
، أو باستخدام الوسيط الثاني لـ $service->render()
$ service -> escape = function ( $ str ) {
return htmlentities ( $ str );
};
$ service -> render ( ' myview.phtml ' , array ( ' title ' => ' My View ' ));
// Or just: $service->title = 'My View';
myview.phtml
< title > < ?php echo $this- > escape($this- > title) ? > </ title >
يتم تجميع العروض وتشغيلها في نطاق $service
بحيث يمكن الوصول إلى جميع طرق الخدمة باستخدام $this
$ this -> render ( ' partial.html ' ) // Render partials
$ this -> sharedData ()-> get ( ' myvar ' ) // Access stored service variables
echo $ this -> query ( array ( ' page ' => 2 )) // Modify the current query string
فيما يلي قائمة بالطرق العامة في الفئات الشائعة التي من المرجح أن تستخدمها. للحصول على مصدر أكثر رسمية لتوثيق الفئة/الطريقة، يرجى الاطلاع على الوثائق التي تم إنشاؤها بواسطة PHPdoc.
$ request ->
id ( $ hash = true ) // Get a unique ID for the request
paramsGet() // Return the GET parameter collection
paramsPost() // Return the POST parameter collection
paramsNamed() // Return the named parameter collection
cookies() // Return the cookies collection
server() // Return the server collection
headers() // Return the headers collection
files() // Return the files collection
body() // Get the request body
params() // Return all parameters
params ( $ mask = null ) // Return all parameters that match the mask array - extract() friendly
param ( $ key , $ default = null ) // Get a request parameter (get, post, named)
isSecure() // Was the request sent via HTTPS?
ip() // Get the request IP
userAgent() // Get the request user agent
uri() // Get the request URI
pathname() // Get the request pathname
method() // Get the request method
method ( $ method ) // Check if the request method is $method, i.e. method('post') => true
query ( $ key , $ value = null ) // Get, add to, or modify the current query string
<param> // Get / Set (if assigned a value) a request parameter
$ response ->
protocolVersion ( $ protocol_version = null ) // Get the protocol version, or set it to the passed value
body ( $ body = null ) // Get the response body's content, or set it to the passed value
status() // Get the response's status object
headers() // Return the headers collection
cookies() // Return the cookies collection
code ( $ code = null ) // Return the HTTP response code, or set it to the passed value
prepend ( $ content ) // Prepend a string to the response body
append ( $ content ) // Append a string to the response body
isLocked() // Check if the response is locked
requireUnlocked() // Require that a response is unlocked
lock() // Lock the response from further modification
unlock() // Unlock the response
sendHeaders ( $ override = false ) // Send the HTTP response headers
sendCookies ( $ override = false ) // Send the HTTP response cookies
sendBody() // Send the response body's content
send() // Send the response and lock it
isSent() // Check if the response has been sent
chunk ( $ str = null ) // Enable response chunking (see the wiki)
header ( $ key , $ value = null ) // Set a response header
cookie ( $ key , $ value = null , $ expiry = null ) // Set a cookie
cookie ( $ key , null ) // Remove a cookie
noCache() // Tell the browser not to cache the response
redirect ( $ url , $ code = 302 ) // Redirect to the specified URL
dump ( $ obj ) // Dump an object
file ( $ path , $ filename = null ) // Send a file
json ( $ object , $ jsonp_prefix = null ) // Send an object as JSON or JSONP by providing padding prefix
$ service ->
sharedData() // Return the shared data collection
startSession() // Start a session and return its ID
flash( $ msg , $ type = ' info ' , $ params = array() // Set a flash message
flashes ( $ type = null ) // Retrieve and clears all flashes of $type
markdown( $ str , $ args , ...) // Return a string formatted with markdown
escape ( $ str ) // Escape a string
refresh() // Redirect to the current URL
back() // Redirect to the referer
query ( $ key , $ value = null ) // Modify the current query string
query ( $ arr )
layout ( $ layout ) // Set the view layout
yieldView () // Call inside the layout to render the view content
render ( $ view , $ data = array ()) // Render a view or partial (in the scope of $response)
partial ( $ view , $ data = array ()) // Render a partial without a layout (in the scope of $response)
addValidator ( $ method , $ callback ) // Add a custom validator method
validate ( $ string , $ err = null ) // Validate a string (with a custom error message)
validateParam ( $ param , $ err = null ) // Validate a param
<callback>( $ arg1 , ...) // Call a user-defined helper
<property> // Get a user-defined property
$ app ->
< callback >( $ arg1 , ...) //Call a user-defined helper
$ validator ->
notNull() // The string must not be null
isLen ( $ length ) // The string must be the exact length
isLen ( $ min , $ max ) // The string must be between $min and $max length (inclusive)
isInt() // Check for a valid integer
isFloat() // Check for a valid float/decimal
isEmail() // Check for a valid email
isUrl() // Check for a valid URL
isIp() // Check for a valid IP
isAlpha() // Check for a-z (case insensitive)
isAlnum() // Check for alphanumeric characters
contains ( $ needle ) // Check if the string contains $needle
isChars ( $ chars ) // Validate against a character list
isRegex ( $ pattern , $ modifiers = '' ) // Validate against a regular expression
notRegex ( $ pattern , $ modifiers = '' )
is<Validator>() // Validate against a custom validator
not<Validator>() // The validator can't match
<Validator>() // Alias for is<Validator>()
تعد اختبارات الوحدة جزءًا مهمًا من تطوير محرك التوجيه مثل كلاين. يمكن أن يكون للميزات المضافة أو إصلاحات الأخطاء تأثيرات سلبية يصعب العثور عليها دون الكثير من الاختبارات، ومن هنا تأتي أهمية اختبار الوحدة.
يستخدم هذا المشروع PHPUnit كإطار عمل لاختبار الوحدة.
جميع الاختبارات موجودة في /tests
وكل اختبار يمتد إلى فئة مجردة AbstractKleinTest
لاختبار المشروع، ما عليك سوى تشغيل php composer.phar install --dev
لتنزيل إصدار شائع من PHPUnit مع Composer وتشغيل الاختبارات من الدليل الرئيسي باستخدام ./vendor/bin/phpunit
راجع دليل المساهمة لمزيد من المعلومات
راجع الويكي لمزيد من المعلومات
(ترخيص معهد ماساتشوستس للتكنولوجيا)
حقوق الطبع والنشر (ج) 2010 كريس أوهارا [email protected]
يُمنح الإذن مجانًا لأي شخص يحصل على نسخة من هذا البرنامج وملفات الوثائق المرتبطة به ("البرنامج")، للتعامل في البرنامج دون قيود، بما في ذلك، على سبيل المثال لا الحصر، حقوق الاستخدام والنسخ والتعديل والدمج. ونشر و/أو توزيع وترخيص من الباطن و/أو بيع نسخ من البرنامج، والسماح للأشخاص الذين تم توفير البرنامج لهم بالقيام بذلك، وفقًا للشروط التالية:
يجب تضمين إشعار حقوق الطبع والنشر أعلاه وإشعار الإذن هذا في جميع النسخ أو الأجزاء الكبيرة من البرنامج.
يتم توفير البرنامج "كما هو"، دون أي ضمان من أي نوع، صريحًا أو ضمنيًا، بما في ذلك، على سبيل المثال لا الحصر، ضمانات القابلية للتسويق والملاءمة لغرض معين وعدم الانتهاك. لا يتحمل المؤلفون أو أصحاب حقوق الطبع والنشر بأي حال من الأحوال المسؤولية عن أي مطالبة أو أضرار أو مسؤولية أخرى، سواء في إجراء العقد أو الضرر أو غير ذلك، الناشئة عن أو خارج أو فيما يتعلق بالبرنامج أو الاستخدام أو المعاملات الأخرى في برمجة.