Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Organized and expanded manual #178

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
399 changes: 20 additions & 379 deletions README.md

Large diffs are not rendered by default.

100 changes: 100 additions & 0 deletions manual/API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# API

Below is a list of the public methods in the common classes you will most likely use. For a more formal source
of class/method documentation, please see the [PHPdoc generated documentation](http://chriso.github.io/klein.php/docs/).

```php
$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>()
```
115 changes: 115 additions & 0 deletions manual/Examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Examples

*Hello World* - Obligatory hello world example

```php
<?php
require_once __DIR__ . '/vendor/autoload.php';

$klein = new \Klein\Klein();

$klein->respond('GET', '/hello-world', function () {
return 'Hello World!';
});

$klein->dispatch();
```

*Example 1* - Respond to all requests

```php
$klein->respond(function () {
return 'All the things';
});
```

*Example 2* - Named parameters

```php
$klein->respond('/[:name]', function ($request) {
return 'Hello ' . $request->name;
});
```

*Example 3* - [So RESTful](http://bit.ly/g93B1s)

```php
$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) {
//
}
});
```

*Example 4* - Sending objects / files

```php
$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');
$service->$send($report);
});

$klein->respond('/report/latest', function ($request, $response, $service) {
$service->file('/tmp/cached_report.zip');
});
```

*Example 5* - All together

```php
$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 third 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>
```
49 changes: 49 additions & 0 deletions manual/Flash_Messages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Flash Messages

Klein provides a Flash Message system, which allows you to store messages for the user in the session array, to be presented to the user at a later time, in a future request.

They usually look something like this: http://getbootstrap.com/components/#alerts

## Create

To store such a message, from inside your route callback, you would call something like:

```php
<?php
$service->flash('Do *NOT* go in there!','warning');
?>
```

The first parameter is a string containing the message you want sent to the user. You can use basic markdown syntax (basically just links, bold, and italics), which will be converted to HTML during rendering.

The second parameter is a message type. This is an arbitrary string. You can make up whatever types make sense for your app. This parameter is optional. If you leave it blank, the default value 'info' will be used.

## Retrieve

The flash messages are stored in $_SESSION['__flashes']. However, you should not access them directly. To retrive them, you use `Klein\ServiceProvider::flashes()`. This method retrieves and clears all the flash messages, or all the flash messages of a given type.

If not type parameter is passed to the method, it returns an array of flashes, grouped by type, so you can foreach and echo them. If you're using the Klein templating system, then you can call the ServiceProvider from the template as `$this`.

So in your template, you would have something like:

```php
<? foreach($this->flashes() as $type=>$messages): ?>
<? foreach($messages as $msg): ?>
<div class="alert alert-<?= $type ?>"><?= $msg ?>
<? endforeach; ?>
<? endforeach; ?>
```

Note that we first loop through the types, and then for each type, we loop through the messages. The code above will format the flash messages appropriately to work with [Bootstrap](http://getbootstrap.com), assuming your types correspond to theirs (success, info, warning, or danger).

## Caution

The two methods involved in handling flash messages are very similar, but not interchangeable. The singular method `Klein\ServiceProvider::flash()` creates a flash message, while the plural method `Klein\ServiceProvider::flashes()` retrieves them.

## More Info

+ http://chriso.github.io/klein.php/docs/classes/Klein.ServiceProvider.html#method_flashes
+ http://chriso.github.io/klein.php/docs/classes/Klein.ServiceProvider.html#method_flash
+ http://chriso.github.io/klein.php/docs/classes/Klein.ServiceProvider.html#merkdown

Source: http://stackoverflow.com/a/21195011/1004008
69 changes: 69 additions & 0 deletions manual/HTTP_Errors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# HTTP Errors

To handle 404 errors, or any HTTP error, you can add a special handler alongside your routes. You simply pass the handler method a callback, much like you would a route. The callback receives the following parameters:

* int `$code` The HTTP error code
* Klein `$router` The router instance
* RouteCollection `$matched` The collection of routes that were matched in dispatch
* array `$methods_matched` The HTTP methods that were matched in dispatch
* HttpExceptionInterface `$http_exception` The exception that occurred

Following are a couple examples:

```php
<?php
// Using exact code behaviors via switch/case
$klein->onHttpError(function ($code, $router) {
switch ($code) {
case 404:
$router->response()->body(
'Y U so lost?!'
);
break;
case 405:
$router->response()->body(
'You can\'t do that!'
);
break;
default:
$router->response()->body(
'Oh no, a bad error happened that caused a '. $code
);
}
});

// Using range behaviors via if/else
$klein->onHttpError(function ($code, $router) {
if ($code >= 400 && $code < 500) {
$router->response()->body(
'Oh no, a bad error happened that caused a '. $code
);
} elseif ($code >= 500 && $code <= 599) {
error_log('uhhh, something bad happened');
}
});
```

The instructions above represent the current recommended technique for handling HTTP errors. Below is the older method, which should still work, but **may be deprecated in future.**

Add a route for `404` as your *last* route. If no other routes are matched, the specified callback will be called.

```php
<?php
$klein->respond('404', function ($request) {
$page = $request->uri();
echo "Oops, it looks like $page doesn't exist..\n";
});
```

**But I need some other route(s) for setting up layouts, etc.**

If you don't want a certain `respond()` call to be counted as a match, just call it without a route:

```php
<?php
$klein->respond(function ($request, $response, $app) {
$response->layout('layout.phtml');
//etc.
});
```
23 changes: 23 additions & 0 deletions manual/Lazy_Services.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Lazy services

Services can be stored **lazily**, meaning that they are only instantiated on
first use.

``` php
<?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;
});
```
23 changes: 23 additions & 0 deletions manual/Response_Chunking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Response Chunking

Read [this article](http://weblog.rubyonrails.org/2011/4/18/why-http-streaming) to understand how response chunking works and how it might benefit your app.

To send a string as a chunk

```php
$response->chunk($str);
```

To flush the contents of the output buffer as a response chunk

```php
$response->chunk();
```

After calling `chunk()`, views will be chunked too

```php
$response->render('mytemplate.phtml');
```

*Note: calling `$response->chunk()` for the first time sets the appropriate header (`Transfer-Encoding: chunked`).*
Loading