Favourite Kohana Tips & Features? [closed]
Inspired from the other community wikis, I'm interested in hearing abo开发者_运维百科ut the lesser known Kohana tips, tricks and features.
- Please, include only one tip per answer.
- Add Kohana versions if necessary.
This is a community wiki.
Generating Form::select() options from database result
Kohana 3.1 and 3.0
$options = ORM::factory('model')
->order_by('title','ASC')
->find_all()
->as_array('id','title');
$select = Form::select('name', $options);
It should be noted this is not restricted to the ORM and can be used on all database results (they all support as_array). See the database results information for more details.
If you want to add a default option:
$options = Arr::merge(array('Please select a value.'), $options);
Show last query executed
Kohana 3.1 and 3.0
echo Database::instance()->last_query
Taken from In Kohana 3, how do you figure out errors made during a query?.
Set Kohana::$environment
Paste these lines to your .htaccess
:
SetEnvIf SERVER_ADDR "^(127\.0\.0\.1|::1)$" KOHANA_ENV=development
SetEnvIf SERVER_ADDR "^((?!127\.0\.0\.1|::1).)*$" KOHANA_ENV=production
now, if you're on localhost, you are in development mode, otherwise you're in production mode
Edit: Added support for IPv6
The difference between this->request->route->uri()
and this->request->uri()
(Kohana 3)
// Current URI = welcome/test/5
// Using default route ":controller/:action/:id"
// This returns "welcome/test/5"
echo $this->request->uri();
// This returns "welcome/test1/5"
echo $this->request->uri(array( 'action' => 'test1' ));
// This returns "welcome/index"
echo $this->request->route->uri();
// This returns "welcome/test1"
echo $this->request->route->uri(array( 'action' => 'test1' ));
As you can see, $this->request->route->uri() uses current route defaults (id is null), while $this->request->uri() applies current uri segments.
Add data to pivot tables using ORM
ORMs add
function accepts a third parameter where you can specify additional data to be saved on the 1pivot table1.
For example, if a user has many roles and a role has many users (through a table named 1roles_users1), you can save information to the 1pivot table1 by passing an array of column keys and data values as the 3rd argument to the add
method.
Kohana 3.1
Not supported. The alternative would be to load the pivot table
and add the data as you would with any other table.
Kohana 3.0
$user->add('role', $role, array('date_role_added' => time()));
where $role
is ORM::factory('role', array('name' => 'user'));
Turn off auto_rendering for AJAX requests
These code samples assume you're extending from the template controller.
Kohana 3.1
public function before()
{
parent::before();
if (Request::current()->is_ajax())
{
$this->auto_render = FALSE;
}
}
Kohana 3.0
public function before()
{
parent::before();
if (Request::$is_ajax)
{
$this->auto_render = FALSE;
}
}
Maintainable routes
Instead of hardcoding anchor locations in your HTML and PHP, it's a good idea to reverse routing. This essentially means you define route locations and then use those; If you ever need to change the location it's done in one place and not hundreds.
Routes can be defined anywhere, but it's good practice to put them into the application bootstrap or your modules bootstrap (init.php).
They are set as follows:
Route::set('name', '<controller>(/<action>)', array('action' => 'login|logout');
- Route name
- The URL path to match against.
- A regular expression to limit what the
<part>
is matched against.
When a part is surrounded by brackets, that part is optional. If a user has not provided a part and you want to provide a default value, then use the defaults method to specify values.
->defaults(array('action' => 'login'));
Kohana 3.1 and 3.0
The following code is now used for having reversable routes. The URL path can be updated and all your URLs should work as before.
Route::url('name', array('controller' => 'user', 'action' => 'login'));
Set base_url
automatically:
Kohana::init(array(
// ...
'base_url' => dirname($_SERVER['SCRIPT_NAME']),
// ...
));
If your site is hosted at 1&1, you should use:
Kohana::init(array(
// ...
'base_url' => substr($_SERVER["SCRIPT_NAME"], 0, strpos($_SERVER["SCRIPT_NAME"], basename($_SERVER["SCRIPT_FILENAME"])));
// ...
));
(taken from Gallery3 config file )
Checking for an internal request
These are known as sub-requests. Take a look at Sam de Freyssinets article: Scaling Web Applications with HMVC for a more indepth explanation. Notice the initial vs instance difference between versions.
Kohana 3.1
if (Request::initial() !== Request::current())
{
print 'Internal called made with Request::factory';
}
Kohana 3.0
if (Request::instance() !== Request::current())
{
print 'Internal called made with Request::factory';
}
HMVC + AJAX = is_remote()
This function checks both - the internal and AJAX requests. It might be handy if some parts of the page are initially loaded using HMVC technique, and can be then reloaded with AJAX. Place it withing some base controller, from which you extend all your proper controllers (I call it 'base controller'):
public function is_remote()
{
if ($this->request->is_initial())
{
if ($this->request->is_ajax())
{
return TRUE;
}
else
{
return FALSE;
}
}
else
{
return TRUE;
}
}
A shorter (equivalent) way of writing this:
public function is_remote()
{
return ( ! $this->request->is_initial() || $this->request->is_ajax());
}
Hope this helps.
Display an error page
If you need to display an error page, Kohana has built in exceptions for it. Once you've thrown an exception, you can create a custom exception handler and have a HTML error page shown. You'll want a switch to show the real error in development.
Kohana 3.1
throw new HTTP_Exception_404('The article :article was not found',
array(':article' => $article->name));
The 2nd argument provides a way for you to replace strings in the error message.
Kohana 3.0
Doesn't have HTTP exceptions bundled. You should create your own exceptions and handle them. Kohana has a tutorial for this: Kohana - Custom Error Pages
To execute SQL query like TRUNCATE mytable
with prepared statements, pass null
as first param to DB::query()
method. Useful, when query doesn't fit for any of CRUD operations.
精彩评论