klein.php est un routeur rapide et flexible pour PHP 5.3+
php composer.phar require klein/klein
require 'vendor/autoload.php';
Hello World – Exemple de Hello World obligatoire
<?php
require_once __DIR__ . ' /vendor/autoload.php ' ;
$ klein = new Klein Klein ();
$ klein -> respond ( ' GET ' , ' /hello-world ' , function () {
return ' Hello World! ' ;
});
$ klein -> dispatch ();
Exemple 1 - Répondre à toutes les demandes
$ klein -> respond ( function () {
return ' All the things ' ;
});
Exemple 2 - Paramètres nommés
$ klein -> respond ( ' /[:name] ' , function ( $ request ) {
return ' Hello ' . $ request -> name ;
});
Exemple 3 - Tellement RESTful
$ 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 ) {
//
}
});
Exemple 4 - Envoi d'objets/fichiers
$ 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 ' );
});
Exemple 5 - Tous ensemble
$ 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 " );
}
Les fichiers inclus sont exécutés dans la portée de Klein ( $klein
) afin que toutes les méthodes/propriétés de Klein soient accessibles avec $this
Exemple de fichier pour : "controllers/projects.php"
// Routes to "/projects/?"
$ this -> respond ( ' GET ' , ' /? ' , function ( $ request , $ response ) {
// Show all projects
});
Les services peuvent être stockés paresseusement , ce qui signifie qu'ils ne sont instanciés qu'à la première utilisation.
<?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 ;
});
Pour ajouter un validateur personnalisé, utilisez addValidator($method, $callback)
$ service -> addValidator ( ' hex ' , function ( $ str ) {
return preg_match ( ' /^[0-9a-f]++$/i ' , $ str );
});
Vous pouvez valider les paramètres en utilisant is<$method>()
ou not<$method>()
, par exemple
$ service -> validateParam ( ' key ' )-> isHex ();
Ou vous pouvez valider n'importe quelle chaîne en utilisant le même flux.
$ service -> validate ( $ username )-> isLen ( 4 , 16 );
Les méthodes de validation peuvent être chaînées et un message d'exception personnalisé peut être spécifié si/quand la validation échoue
$ service -> validateParam ( ' key ' , ' The key was invalid ' )-> isHex ()-> isLen ( 32 );
[ type_match : nom_param ]
Quelques exemples
* // 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
Quelques exemples plus compliqués
/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
Remarque : toutes les routes qui correspondent à l'URI de la demande sont appelées ; cela vous permet d'incorporer une logique conditionnelle complexe telle que l'authentification de l'utilisateur ou la disposition des vues. par exemple, à titre d'exemple de base, le code suivant encapsulera d'autres routes avec un en-tête et un pied de page
$ klein -> respond ( ' * ' , function ( $ request , $ response , $ service ) { $ service -> render ( ' header.phtml ' ); });
//other routes
$ klein -> respond ( ' * ' , function ( $ request , $ response , $ service ) { $ service -> render ( ' footer.phtml ' ); });
Les routes correspondent automatiquement à l’intégralité de l’URI de la demande. Si vous devez faire correspondre seulement une partie de l'URI de la requête ou utiliser une expression régulière personnalisée, utilisez l'opérateur @
. Si vous devez annuler un itinéraire, utilisez le !
opérateur
// 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/ ' , ...
Vous pouvez envoyer des propriétés ou des assistants à la vue en les attribuant à l'objet $service
ou en utilisant le deuxième argument de $service->render()
$ service -> escape = function ( $ str ) {
return htmlentities ( $ str );
};
$ service -> render ( ' myview.phtml ' , array ( ' title ' => ' My View ' ));
// Or just: $service->title = 'My View';
ma vue.phtml
< title > < ?php echo $this- > escape($this- > title) ? > </ title >
Les vues sont compilées et exécutées dans le cadre de $service
afin que toutes les méthodes de service soient accessibles avec $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
Vous trouverez ci-dessous une liste des méthodes publiques des classes courantes que vous utiliserez probablement. Pour une source plus formelle de documentation de classe/méthode, veuillez consulter la documentation générée par 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>()
Les tests unitaires sont un élément crucial du développement d'un moteur de routage tel que Klein. Les fonctionnalités ajoutées ou les corrections de bogues peuvent avoir des effets indésirables difficiles à trouver sans de nombreux tests, d'où l'importance des tests unitaires.
Ce projet utilise PHPUnit comme framework de tests unitaires.
Les tests résident tous dans /tests
et chaque test étend une classe abstraite AbstractKleinTest
Pour tester le projet, exécutez simplement php composer.phar install --dev
pour télécharger une version commune de PHPUnit avec composer et exécutez les tests depuis le répertoire principal avec ./vendor/bin/phpunit
Voir le guide de contribution pour plus d'informations
Voir le wiki pour plus d'informations
(Licence MIT)
Copyright (c) 2010 Chris O'Hara [email protected]
L'autorisation est accordée par la présente, gratuitement, à toute personne obtenant une copie de ce logiciel et des fichiers de documentation associés (le « Logiciel »), d'utiliser le Logiciel sans restriction, y compris, sans limitation, les droits d'utilisation, de copie, de modification, de fusion. , publier, distribuer, accorder des sous-licences et/ou vendre des copies du Logiciel, et permettre aux personnes à qui le Logiciel est fourni de le faire, sous réserve des conditions suivantes :
L'avis de droit d'auteur ci-dessus et cet avis d'autorisation doivent être inclus dans toutes les copies ou parties substantielles du logiciel.
LE LOGICIEL EST FOURNI « TEL QUEL », SANS GARANTIE D'AUCUNE SORTE, EXPRESSE OU IMPLICITE, Y COMPRIS MAIS SANS LIMITATION LES GARANTIES DE QUALITÉ MARCHANDE, D'ADAPTATION À UN USAGE PARTICULIER ET DE NON-VIOLATION. EN AUCUN CAS LES AUTEURS OU LES TITULAIRES DES DROITS D'AUTEUR NE SERONT RESPONSABLES DE TOUTE RÉCLAMATION, DOMMAGES OU AUTRE RESPONSABILITÉ, QUE CE SOIT DANS UNE ACTION CONTRACTUELLE, DÉLIT OU AUTRE, DÉCOULANT DE, DE OU EN RELATION AVEC LE LOGICIEL OU L'UTILISATION OU D'AUTRES TRANSACTIONS DANS LE LOGICIEL.