Fatal error: Uncaught exception 'Zend_Db_Table_Exception' with message
'No adapter found for Zend_Session_SaveHandler_DbTable' in
C:\wamp\www\hol\library\Zend\Db\Table\Abstract.php on line 755 ( ! )
Zend_Db_Table_Exception: No adapter found for
Zend_Session_SaveHandler_DbTable in
C:\wamp\www\hol\library\Zend\Db\Table\Abstract.php on line 755 Call
Stack
Time Memory Function Location 1 0.0005 373664 {main}( ) ..\init.php:0
2 0.0325 2749720 Zend_Session_SaveHandler_DbTable->__construct(
) ..\init.php:40 3 0.0325 2750168 Zend_Db_Table_Abstract->__construct(
) ..\DbTable.php:207
4 0.0325 2750480 Zend_Session_SaveHandler_DbTable->_setup(
) ..\Abstract.php:268 5 0.0325 2750480 Zend_Db_Table_Abstract->_setup(
) ..\DbTable.php:403
6 0.0325 2750480 Zend_Db_Table_Abstract->_setupDatabaseAdapter(
) ..\Abstract.php:739
Code:
//Configuration consumption
$config = new Zend_Config(require 'config.php');
//Database configuration
$db = Zend_Db::factory($config->database->adapter, array(
'host' => $config->database->params->host,
'username' => $config->database->params->username,
'password' => $config->database->params->password,
'dbname' => $config->database->params->dbname
));
$sess_config = array(
'name' => 'session',
'primary' => array(
'session_id',
'save_path',
'name',
),
'primaryAssignment' => array(
'sessionId',
'sessionSavePath',
'sessionName',
),
'modifiedColumn' => 'modified',
'dataColumn' => 'session_data',
'lifetimeColumn' => 'lifetime',
);
Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_DbTable($sess_config));
//Initialize the session
Zend_Session::start();
config
<?php
// config.php
return array(
'database' => array(
'adapter' => 'Pdo_Mysql',
'params' => array(
'host' => 'localhost',
'username' => 'root',
'password' => '',
'dbname' => 'hol'
)
),
'session' => array(
'name' => 'session',
'primary' => array(
'session_id',
'save_path',
'name',
),
'primaryAssignment' => array(
'sessionId',
'sessionSavePath',
'sessionName',
),
'modifiedColumn' => 'modified',
'dataColumn' => 'session_data',
'lifetimeColumn' => 'lifetime'
)
);
SQL:
CREATE TABLE `session` (
`session_id` char(32) NOT NULL,
`save_path` varchar(32) NOT NULL,
`name` varchar(32) NOT NULL DEFAULT '',
`modified` int,
`lifetime` int,
`session_data` text,
PRIMARY KEY (`Session_ID`, `save_path`, `name`)
);
You didn't post the contents of your config.php, but based on the error I suspect you did not specify an adapter (mysql, pdo, etc).
My config file looks something like (yaml):
database:
adapter: Pdo_Mysql
params:
host: myhost
dbname: mydb
username: myusername
password: mypassword
According to the Zend API docs, you have to specify the adapter like this:
// Set this before you make the call to setSaveHandler()
Zend_Db_Table_Abstract::setDefaultAdapter($db);
Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_DbTable($sess_config));
You either need to call Zend_Db_Table_Abstract::setDefaultAdapter($db) providing the $db object you created in your configuration example, as it appears you don't have a default DB adapter set up given the error, or you need to add the $db object to the $sess_config array so it gets set up as the DB adapter for Zend_Session.
Zend_Session_SaveHandler_DbTable extends Zend_Db_Table_Abstract and any options unknown to Zend_Session_SaveHandler_DbTable (e.g. database configuration options) are then passed to the constructor of Zend_Db_Table_Abstract which sets up the DbTable.
Try this:
$sess_config = array(
'db' => $db, // Pass the $db adapter as the 'db' parameter to Zend_Db_Table_Abstract
'name' => 'session',
'primary' => array(
'session_id',
'save_path',
'name',
),
'primaryAssignment' => array(
'sessionId',
'sessionSavePath',
'sessionName',
),
'modifiedColumn' => 'modified',
'dataColumn' => 'session_data',
'lifetimeColumn' => 'lifetime',
);
Related
I have been playing with the developer preview version of CakePHP 3.0 and I'm stuck trying to get the new ORM working with pagination.
In my PostsController.php I have:
<?php
namespace App\Controller;
use App\Controller\AppController;
class PostsController extends AppController {
public $name = 'Posts';
public $uses = 'Posts';
public $components = ['Paginator'];
public $paginate = [
'fields' => ['Posts.id'],
'limit' => 1,
'order' => [
'Post.id' => 'asc'
]
];
public function index() {
$posts = $this->paginate('Posts');
$this->set('posts', $posts);
}
}
However the paging is working but the data doesn't come back. Apparently this because the data isn't directly returned in the new ORM but an object... Has anyone tried this yet? Knows how to fix the issue to get it working with the paginator?
I've been reading the Migration Guide: http://book.cakephp.org/3.0/en/appendices/orm-migration.html but don't see anything about combining it with the paginator.
Note: I can't debug $posts and show it here because it's about 2000 lines of code containing all sorts of stuff about the ORM. Here's a taster...
object(Cake\ORM\ResultSet) {
[protected] _query => object(Cake\ORM\Query) {
[protected] _table => object(Cake\ORM\Table) {
[protected] _table => 'posts'
[protected] _alias => 'Posts'
[protected] _connection => object(Cake\Database\Connection) {
[protected] _config => array(
'password' => '*****',
'login' => '*****',
'host' => '*****',
'database' => '*****',
'prefix' => '*****',
'persistent' => false,
'encoding' => 'utf8',
'name' => 'default',
'datasource' => object(Cake\Database\Driver\Mysql) {
[protected] _baseConfig => array(
'password' => '*****',
'login' => '*****',
'host' => '*****',
'database' => '*****',
'port' => '*****',
'persistent' => true,
'flags' => array(),
'encoding' => 'utf8',
'timezone' => null,
'init' => array(),
'dsn' => null
)
[protected] _config => array(
'password' => '*****',
'login' => '*****',
'host' => '*****',
'database' => '*****',
'port' => '*****',
'prefix' => '*****',
'persistent' => false,
'encoding' => 'utf8',
'name' => 'default',
'flags' => array(),
'timezone' => null,
'init' => array(),
'dsn' => null
)
[protected] _autoQuoting => false...
So as you can see it's a huge object and presumably the data is somewhere within it.
Apparently this because the data isn't directly returned in the new
ORM but an object...
It's not a bug it's a feature. ;) CakePHP3 returns a ResultSet object as you can see and entity objects for records. You'll have to work with these objects now instead of arrays.
I wounder if you really read the migration guide you've linked because it is all in there:
Cake\ORM\ResultSet - A collection of results that gives powerful tools for manipulating data in aggregate.
Cake\ORM\Entity - Represents a single row result. Makes accessing data and serializing to various formats a snap.
Further down on that page there is even more info about that. Take a look at the ResultSet API. You'll see that it implements Iterator, you can use it like an array:
Controller method:
public function index() {
$this->set('users', $this->Paginator->paginate($this->Users, [
'limit' => 5,
'conditions' => [
'Users.active' => 1
]
]));
}
There is a lot of documentation to read in the doc block of the paginate() method.
View index.ctp:
foreach ($users as $user) {
debug($user);
}
This will show you Entity objects. I'm not pasting the whole long debug output here, just a part of it.
object(Cake\ORM\Entity) {
[protected] _properties => array(
'password' => '*****',
'id' => '52892217-91ec-4e5d-a9f4-1b6cc0a8000a',
'username' => 'burzum',
'slug' => '',
// ...
To get something from the object back just do this:
echo $user->username;
The actual data is in the protected property Entity::$_properties and accessed by __get.
This will be in your controller.
public function index() {
$this->set('users', $this->paginate($this->Users));
$this->set('_serialize', ['users'])
}
This you can put in your action
Paginatore logic
I have Zend Framework project and I decided to use Rediska as Redis client.
Rediska has cache backend adapter for ZF - Rediska_Zend_Cache_Backend_Redis.
I fetch from DB collection of objects and try to save it in cache but get error: Connection read timed out. My example of code:
$rediskaOptions = array(
'name' => 'cache',
'namespace' => 'Cache_',
'servers' => array( 'cache' => array(
'host' => Rediska_Connection::DEFAULT_HOST,
'port' => Rediska_Connection::DEFAULT_PORT,
'password' => 'qwerty'
)
)
);
$cache = Zend_Cache::factory('Core', 'Rediska_Zend_Cache_Backend_Redis',
array('lifetime' => NULL, 'automatic_serialization' => true),
array('rediska' => $rediskaOptions), false, true
);
$cacheId = 'news_main';
if (!($topics = $cache->load($cacheId))) {
$topics = DAOFactory::getInstance()->getTopicDAO()->fetchTopic(1);
$cache->save($topics, $cacheId);
}
Size of content after serialization is 26787 bytes.
Maybe Redis have size limitations for sending?
If it helps, I am using Rediska with ZF as well. Here is how I set it up.
$options = array(
'servers' => array(
array( 'host' => '127.0.0.1',
'port' => 6379,
'alias' => 'cache'
),
//'name' => 'cache',
//'namespace' => 'Cache_'
)
);
$rediska = new Rediska($options);
$frontendOptions = array('automatic_serialization' => true);
$backendOptions = array('rediska' => $rediska);
$cache = Zend_Cache::factory( 'Core',
'Rediska_Zend_Cache_Backend_Redis',
$frontendOptions,
$backendOptions,
false,
true
);
A difference I see is in the backend options. I point rediska to a rediska instance.
In my controller I have two functions that pull all records from the db with a status = 4. In one function it works fine. I copied the find all statement from the working function:
$this->set('completed', $this->Topic->find('all', array('fields' => array(
'Topic.creator','Topic.link','Topic.id', 'Topic.topic_name', 'Topic.info', 'Topic.priority', 'Topic.user_id',
'Topic.completed','Topic.created', 'Topic.status','User.name','User.id','Topic.category','Topic.tags'),'conditions' => array(
'Topic.status' => 4))));
But in the new function the $completed array doesn't seem to exist. The debug statement is just a blank line. If I debug the sql log using debug($this->Topic->getDataSource()->getLog()); this is the returned array:
Array
(
[log] => Array
(
[0] => Array
(
[query] => SELECT `Topic`.`creator`, `Topic`.`link`, `Topic`.`id`, `Topic`.`topic_name`, `Topic`.`info`, `Topic`.`priority`, `Topic`.`user_id`, `Topic`.`completed`, `Topic`.`created`, `Topic`.`status`, `User`.`name`, `User`.`id`, `Topic`.`category`, `Topic`.`tags` FROM `topics` AS `Topic` LEFT JOIN `users` AS `User` ON (`Topic`.`user_id` = `User`.`id`) LEFT JOIN `events` AS `Event` ON (`Event`.`topic_id` = `Topic`.`id`) WHERE `Topic`.`status` = 4
[affected] => 9
[numRows] => 9
[took] => 0
)
)
[count] => 1
[time] => 0
)
The SQL statement in the log works. If I plug in into mySQL it produces results. And the affected and numRows field show the correct number of records. But the produced data isn't being set to variables. Any ideas would be greatly appreciated. My boss and I are stumped. Here are both complete functions:
public function dashboard(){
$this->set('completed', $this->Topic->find('all', array('fields' => array(
'Topic.creator','Topic.link','Topic.id', 'Topic.topic_name', 'Topic.info', 'Topic.priority', 'Topic.user_id',
'Topic.completed','Topic.created', 'Topic.status','User.name','User.id','Topic.category','Topic.tags'),'conditions' => array(
'Topic.status' => 4))));
$this->set('total_inprogress_release', $this->Topic->find('count', array('conditions' => array(
'OR' => array('status <>' => 4,'status <>' => 0),
'priority' => 4))));
$this->set('upcoming_events', $this->Topic->Event->find('all'));
$this->Topic->virtualFields['count'] = 'COUNT(*)';
$this->set('graph_data', $this->Topic->find('chart', array('fields' => array('status_txt', 'priority_txt', 'count'), 'group' => array('status', 'priority'),
'chart' => array(
'xaxisTitle' => 'Status',
'yaxisLabels' => array('Release', 'Company', 'News'),
'xaxisLabels' => array('Open','In Progress','Completed'),
'yaxis' => 'Topic.priority_txt',
'xaxis' => 'Topic.status_txt',
'data' => 'Topic.count'
))));
}
And here's the nonworking function:
public function completed(){
$foo = $this->Topic->find('all', array('fields' => array(
'Topic.creator','Topic.link','Topic.id', 'Topic.topic_name', 'Topic.info', 'Topic.priority', 'Topic.user_id',
'Topic.completed','Topic.created', 'Topic.status','User.name','User.id','Topic.category','Topic.tags'),'conditions' => array(
'Topic.status' => 4)));
debug($foo);
debug($this->Topic->getDataSource()->getLog());
}
After several hours of tracking the data until we figured out where it was being lost, we found that the problem was some of the data in the database. It was encoded and it was causing a while statement in the core cake files to reset when it encountered said data. The solution was to alter Config/database.php as such:
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'login',
'password' => 'Password',
'database' => 'database',
'prefix' => '',
'encoding' => 'utf8',//this line allows the database to read utf8 data.
);
}
I think the relationships may be causing an issue here. Try this in the completed function and pr($foo) the results:
$foo = $this->Topic->find('all', array(
'fields' => array(
'Topic.creator',
'Topic.link',
'Topic.id',
'Topic.topic_name',
'Topic.info',
'Topic.priority',
'Topic.user_id',
'Topic.completed',
'Topic.created',
'Topic.status',
'User.name',
'User.id',
'Topic.category',
'Topic.tags'
),
'conditions' => array(
'Topic.status' => 4,
),
'joins' => array(
array(
'table' => 'users',
'alias' => 'User',
'type' => 'LEFT',
'conditions' => array(
'Topic.user_id = User.id'
),
),
),
'recursive' => -1,
));
I suspect you will get the results you are looking for.
I've tried to do some tests, but cakephp doesn't create de test_{tablename} tables! He is trying to use de original tables.
Database config:
var $test = array(
'driver' => 'mysql',
'persistent' => false,
'host' => '127.0.0.1',
'login' => 'root',
'password' => '',
'database' => 'tests_clubpets',
'encoding' => 'utf8'
);
Fixture:
class AdminFixture extends CakeTestFixture {
var $name = 'Admin';
var $fields = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
...
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB')
);
var $records = array(
array(
'id' => 1,
'nome' => 'Lorem ipsum dolor sit amet',
...
);
}
Model:
class AdminTestCase extends CakeTestCase {
var $fixtures = array('app.admin');
function startTest() {
$this->Admin =& ClassRegistry::init('Admin');
}
function endTest() {
unset($this->Admin);
ClassRegistry::flush();
}
}
What can be wrong?
when you create the $test database connection, cake should be trying to make the tables in that database. according to your code that should be in tests_clubpets. make sure the database is created and that the user has permissions on the table. also check you did not make any typeo's
if you want to have your tables named test_{tablename}, use:
'prefix' => 'test_',
I'm attempting to use the session database with Kohana 3.
I have setup the mysql database as described here: http://kerkness.ca/wiki/doku.php?id=sessions_and_cookies
I am setting session variables like so:
Session::instance('database')->set('uid', $user_id);
However when I go to fetch the data back later on a different page or refresh it returns NULL.
Session::instance('database')->get('uid', NULL);
But if I put them right next to each other it works fine... i.e.
Session::instance('database')->set('uid', $user_id);
Session::instance('database')->get('uid', NULL);
Any ideas as to why this is happening?
I have also setup session.php in my config folder which looks like this:
<?php
return array(
'cookie' => array(
'name' => 'cookie',
'encrypted' => TRUE,
'lifetime' => 43200,
),
'native' => array(
'name' => 'session',
'encrypted' => TRUE,
'lifetime' => 43200,
),
'database' => array(
'group' => 'default',
'table' => 'sessions',
),
);
?>
Cheers,
Thomas.
Update the session.php file to look like this:
<?php
return array(
'cookie' => array(
'name' => 'session_cookie',
'encrypted' => TRUE,
'lifetime' => 43200,
),
'native' => array(
'name' => 'session_native',
'encrypted' => TRUE,
'lifetime' => 43200,
),
'database' => array(
'name' => 'session_database',
'group' => 'default',
'table' => 'sessions',
),
);
?>
Problem was by default the sessions are called 'session'.
So I renamed each adapter and it has fixed the issue.