How to use cache in cakephp - php

I have a site in cakephp and I have configure cache for It.
In bootstrap.php I have write this line like the guide in the site of cakephp:
Cache::config('default', array('engine' => 'File'));
Cache::config('short', array(
'engine' => 'File',
'duration' => '+1 hours',
'path' => CACHE,
'prefix' => 'cake_short_'
));
// long
Cache::config('long', array(
'engine' => 'File',
'duration' => '+1 week',
'probability' => 100,
'path' => CACHE . 'long' . DS,
));
In my controller I want to cache some query that are call many times like this:
class User extends AppModel {
public function get($alias) {
$result = Cache::read('get_users', 'longterm');
if (!$result) {
$result = $this->find('all', array('conditions' =>array( 'alias' => $alias)));
Cache::write('get_users', $result, 'longterm');
}
return $result;
}
}
I want to know if is efficient to cache query with parameters (alias) or is better to cache only query with not parameters like this?
$result = $this->find('all', array('order' =>'id'));
Because my doubt is: is useful to cache query with parameter or not? Is a good way to make more efficient the speed of the site?

Related

Yii::app()->user->id sometimes gives empty result

Hosted on Heroku
Yii 1.14
PHP 5.6
A stranger error when Yii::app()->user->id returns the id sometimes but at other times returns empty. The same page load results in this strange behaviour.
I check for this in a parent class called AdminController.php
class AdminController extends CController
{
public $partnerCount;
public $vendorCount;
public $plantationMarkers;
public function init()
{
echo Yii::app()->user->id;
if(empty(Yii::app()->user->id)) {
echo 'User id empty: '. Yii::app()->user->id;
//$this->redirect(Yii::app()->createAbsoluteUrl('admin/auth/login'));
exit;
return false;
}
elseif(!Yii::app()->user->checkAccess(User::PARTNER)) {
$this->layout = 'column1';
$this->render('/auth/not-authorized');
return false;
}
$this->partnerCount = $this->getPartnerCount();
$this->vendorCount = $this->getVendorCount();
$this->plantationMarkers = $this->getPlantationMarkers();
return true;
}
So in this code 'User id empty: ' is echoed in some cases while in other cases I get the id.
The point is with no change in code how can this work at some time while not at other times.
Solved by changing the session to be stored in DB table. I am not sure but there was some issue with Yii storing session on the server under Heroku.
The change is required in the config array under 'components'.
From :
'session' => array(
'class' => 'CHttpSession',
'timeout' => 2400,
'cookieParams' => array(
'httpOnly' => true,
'secure' => false,
),
),
To :
'session' => array(
'timeout' => 2400,
'cookieParams' => array(
'httpOnly' => true,
'secure' => false,
),
'class' => 'CDbHttpSession',
'connectionID' => 'db',
'sessionTableName' => 'lig_session',
),

Zend framework 2 routing required query parameters not working

I'm working on zf2 to make one of my routes only accessible when a query string parameter is passed. Otherwise, it will not. I've added a filter on the route section but when accessing the page without the query parameter, it is still going thru.
'router' => array(
'routes' => array(
'show_post' => array(
'type' => 'segment',
'options' => array(
'route' => '[/]show/post/:filter',
'constraints' => array(
'filter' => '[a-zA-Z0-9-.]*',
),
'defaults' => array(
'controller' => 'blog_controller',
'action' => 'show'
)
),
),
),
),
http://example.com/show/post/?postId=1235 = This should work
http://example.com/show/post?postId=1235 = This should work
http://example.com/show/post/ = This should not work
http://example.com/show/post = This should not work
The way you currently have this setup you would have to structure your url like this
http://example.com/show/post/anything?postId=1235
I think what you are wanting is to structure your route like this
'route' => '[/]show/post',
Not sure what you are trying to accomplish with [/] before show though, you are making that dash optional there?
I would write it like this
'route' => '/show/post[/:filter]',
This way you can structure your urls like this
http://example.com/show/post/anything?postId=1235
or
http://example.com/show/post?postId=1235
Then in your action you can access those parameters like this
$filter = $this->params('filter');
$post_id = $this->params()->fromQuery('post_id');
or just
$post_id = $this->params()->fromQuery('post_id');
***************UPDATE***************
It looks like zf2 used to include what you are trying to do and removed it because of security reasons.
http://framework.zend.com/security/advisory/ZF2013-01
Don't try to bend ZF2 standard classes to your way. Instead write your own route class, a decorator to the segment route, which will do exactly as you please:
<?php
namespace YourApp\Mvc\Router\Http;
use Zend\Mvc\Router\Http\Segment;
use use Zend\Mvc\Router\Exception;
use Zend\Stdlib\RequestInterface as Request;
class QueryStringRequired extends Segment
{
public static function factory($options = [])
{
if (!empty($options['string'])) {
throw new Exception\InvalidArgumentException('string parameter missing');
}
$object = parent::factory($options);
$this->options['string'] = $options['string'];
return $object;
}
public function match(Request $request, $pathOffset = null, array $options = [])
{
$match = parent::match($request, $pathOffset, $options);
if (null === $match) {
// no match, bail early
return null;
}
$uri = $request->getUri();
$path = $uri->getPath();
if (strpos($path, $this->options['string']) === null) {
// query string parametr not found in the url
// no match
return null;
}
// no query strings parameters found
// return the match
return $match;
}
}
This solution is very easy to unit test as well, it does not validate any OOP principles and is reusable.
Your new route definition would look like this now:
// route definition
'router' => array(
'routes' => array(
'show_post' => array(
'type' => YourApp\Mvc\Router\Http\QueryStringRequired::class,
'options' => array(
'string' => '?postId=',
'route' => '[/]show/post/:filter',
'constraints' => array(
'filter' => '[a-zA-Z0-9-.]*',
),
'defaults' => array(
'controller' => 'blog_controller',
'action' => 'show'
)
),
),
),
),

how to write MySQL queries in cakephp 3

I am trying to do login system in cakephp 3.
Here is the query:
$user_details = $this->User->find('first', ['conditions'=>['email_id'=$email, 'password'=>$password]]);
if(!empty($user_details)){
$this->request->session()->write('user_email'=>$user_details['email_id']);
$this->request->session->write('user_id'=>$user_details['id');
}
Can you tell the differences from cakephp 2 to cakephp 3 about writing queries?
try this query its work fine for you...
$user_details = $this->User->find('first', ['conditions'=>['User.email_id'=$email, 'User.password'=>$password]]);
otherwise you get help from http://book.cakephp.org/3.0/en/controllers/components/authentication.html
For authenticating users you should use the Authentication component. This serves as the best implementation within CakePHP as it automatically binds all the data to the server and request.
public function initialize()
{
parent::initialize();
$this->loadComponent('Auth', [
'loginAction' => [
'controller' => 'Users',
'action' => 'login',
'plugin' => 'Users'
],
'authError' => 'Did you really think you are allowed to see that?',
'authenticate' => [
'Form' => [
'fields' => ['username' => 'email']
]
],
'storage' => 'Session'
]);
}
Please refer to the documentation: http://book.cakephp.org/3.0/en/controllers/components/authentication.html
To answer your original question
Cake 2 uses an automagical function with an array structure for building queries which is quite devious. The query is executed directly on call.
array(
'conditions' => array('Model.field' => $thisValue), //array of conditions
'recursive' => 1, //int
//array of field names
'fields' => array('Model.field1', 'DISTINCT Model.field2'),
//string or array defining order
'order' => array('Model.created', 'Model.field3 DESC'),
'group' => array('Model.field'), //fields to GROUP BY
'limit' => n, //int
'page' => n, //int
'offset' => n, //int
'callbacks' => true //other possible values are false, 'before', 'after'
)
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html
Within Cake 3 the query is built using a query builder object. This modifies the SQL on every subsequent call. It is only executed after you call it to.
$query = $articles->find('all')
->where(['Articles.created >' => new DateTime('-10 days')])
->contain(['Comments', 'Authors'])
->limit(10);
Here the an object is manipulated with a referenced SQL on every call (where, contain, limit).
The query is executed after you apply execute(), first(), toArray() etc, where toArray() returns the data set as an array and others as an object.
Further reading: http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html

Query caching not working in Yii framework

I've a table containing more than 27,000 records. I want to fetch all data in Dropdown list. For that I've implemented cache but it seems to be not working as its getting very slow and showing blank page (Sometime browser is getting hanged).
Following is my code (I am using yiiboilerplate):
Configuration of backend/config/main.php in component array:
'cache' => array(
//'class' => 'system.caching.CMemCache',
'class' => 'system.caching.CDbCache',
'connectionID' => 'db',
),
In View page:
$dependency = new CDbCacheDependency('SELECT MAX(bank_id) FROM bank');
$bank = CHtml::listData(Bank::model()->cache(1000, $dependency)->findAll('is_active=1', array('order' => 'name')), 'bank_id', 'concatened');
echo $form->dropDownListRow($model, 'bank_id', $bank, array(
'empty' => 'Select'
));
I think 27000 records is not big data but still its getting very slow and I want to implement cache in my entire application.
Is my configuration correct? Where I am going wrong?
Thanks
I think your parameters in findAll is incorrect.
It should be:
Bank::model()
->cache(1000, $dependency)
->findAll([
'select' => 'bank_id',
'order' => 'name ASC', // if it is in ascending order
'condition' => 'is_active = 1'
]);
I don't know what concatened so I just ignored it. But you can always use scopes for your conditions.

Cache query cakephp

I have a site developed in cakephp. I want to cache a query. I have read the documentation and I have in my bootstrap.php this:
Cache::config('default', array('engine' => 'File'));
Cache::config('short', array(
'engine' => 'File',
'duration' => '+1 hours',
'path' => CACHE,
'prefix' => 'cake_short_'
));
// long
Cache::config('long', array(
'engine' => 'File',
'duration' => '+1 week',
'probability' => 100,
'path' => CACHE . 'long' . DS,
));
My controller to store the query is this:
public function test_view () {
$product_general = Cache::read('product_general_query', 'longterm');
if (!$product_general) {
echo("test");
$product_general = $this->Product->query('SELECT DISTINCT * FROM products');
Cache::write('product_general_query', $product_general, 'longterm');
}
$this->set('product_general', $product_general);
}
Everytime that I enter into the page it print me "test" because doesn't find the query into the cache. Where is the problem? Have I miss something?
You named your cache configuration 'long' inside your core.php but using configuration 'longterm' inside your action
Also, If you have enabled debugging (e.g. debug set to 1 or 2 in your core.conf), the cache duration may be set to 10 seconds automatically. Not sure if this will apply to your own cache definitions as well though

Categories