I have next settings in application.ini
resources.db.adapter = PDO_MYSQL
resources.db.params.host = localhost
resources.db.params.username = some
resources.db.params.password = somepass
resources.db.params.dbname = name
resources.db.isDefaultTableAdapter = true
have 2 similar models Zend_db_table_Abstract
in first model i use
$db = Zend_Db_Table::getDefaultAdapter();
all work fine
but if i try use same in the second
i see next message
Exception information:
Message: No adapter for type Zend_Db_Statement_Pdo
i tried to take adapter using another method but i see same Message
trying
in class extended zend_db_table_abstract
$this->getDefaultAdapter
Registry var db in Zend_registry from bootstrap
all time i see same message
Any idea ?
$db = Zend_Db_Table::getDefaultAdapter();
$db->query('SET #rank:=0');
try this
Related
I'm working on some project in my company, and client asked me to change few things in database. Project was not done by us. After few hours of work I saw these config lines:
resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "localhost"
resources.db.params.dbname = "db"
resources.db.params.username = "db-user"
resources.db.params.password = "db-password"
resources.db.params.charset = "utf8"
resources.db.params.driver_options.1006 = true
resources.db.params.driver_options.1000 = true
Can anyone tell me what exactly these driver options mean? I was googling around for some time and couldn't find any other answer but this: these are driver specific options...
MYSQL_ATTR_DIRECT_QUERY = 1006
MYSQL_ATTR_USE_BUFFERED_QUERY = 1000
http://www.wolfcms.org/phpdoc/latest/Framework/Record.html
For info on those options: http://php.net/manual/en/ref.pdo-mysql.php
I have been looking for a solution that allows load data queries with zend framework like:
LOAD XML LOCAL INFILE '$dbFile' INTO TABLE mytable ROWS IDENTIFIED BY '<object>';
When I try to execute this query, i get the following error:
Warning: PDO::exec() [pdo.exec]: LOAD DATA LOCAL INFILE forbidden
However if I output the query and copy/paste it into an editor like HeidiSQL the query works.
I searched for an answer and found that I should set the driver option PDO::MYSQL_ATTR_LOCAL_INFILE but it does not seem to work.
I would like to use application.ini to set the driver option:
resources.multidb.mydb.adapter = "Pdo_Mysql"
resources.multidb.mydb.dbname = "mydb"
resources.multidb.mydb.username = "myuser"
resources.multidb.mydb.password = "mypass"
resources.multidb.mydb.driver_options.PDO::MYSQL_ATTR_LOCAL_INFILE = true
resources.multidb.mydb.driver_options.1001 = true
I tried it the following way too but got the same error:
$config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', 'testing');
$dbParams = $config->resources->multidb->mydb->toArray();
$dbParams['driver_options'] = array(PDO::MYSQL_ATTR_LOCAL_INFILE => '1');
$db = Zend_Db::factory($config->resources->multidb->mydb->adapter, $dbParams);
Am I overlooking something? Or maybe setting the options wrong? I also read that mysql must be compiled with --enable-load-data or something but the query works with an sql editor so it should work through php.
I found an interesting implementation of local infiles in the Rend (Rapid Zend) Framework.
Basically, the file has a class for the PDO object and has a method like this:
/**
* Set the local infile flag
*
* #param boolean $allowLocalInfile
* #return Rend_Factory_Database_Pdo_Mysql
*/
public function setAllowLocalInfile($allowLocalInfile)
{
$this->_options["driver_options"][PDO::MYSQL_ATTR_LOCAL_INFILE] = $allowLocalInfile;
return $this;
}
I'm sure some more browsing in that open source repository would reveal some tricks to solve your problem.
Here is how i am creating the zend db connection
$DB = new Zend_Db_Adapter_Pdo_Mysql(array("host" => "localhost","username" => "root", "password" => "admin123", "dbname" => "user_management"));
The problem i have is that in my model files mysql_query have been used to run queries. I want to pass the DB connection from the controller to the model. How do i get the php factory mysql link resource directly from the zend db connection object.
PS: I have tried adding
$db = $DB->getConnection();
This isnt working, I think it maybe because of some include file missing.
I like to open the connection by application.ini
resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "localhost"
resources.db.params.username = "root"
resources.db.params.password = ""
resources.db.params.dbname = "dbtest"
resources.db.isDefaultTableAdapter = true
If you're using Zend Framework 1.8+ (and if you use resources.db in application.ini), you can get an instance of db Adapter through Zend_Db_Table everywhere:
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
Unfortunately, mysql_connect() returns a different db connection than the PDO adapter. See:
Getting a PHP PDO connection from a mysql_connect()?
Perhaps you can use the Mysqli adapter rather than the PDO MySQL adapter?
have defined different models and modelMappers in my php project.
my folders are structured as follows
-application
--models
---DbTable
----modelName
---modelMapperName
modelName.php
class Application_Model_DbTable_ModelName extends Zend_Db_Table_Abstract{
}
modelMapper.php
class Application_Model_ModelMapper
{
}
everytime i try to access the values in my database by creating an instance of my mapper in the controller i get the message No adapter found for Application_Model_DbTable_ModelName
i thought this can be an issue with the autoloader and added the following code in the bootstrap,
$loader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Application',
'basePath' => APPLICATION_PATH
));
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
return $loader;
but it still didnt work, can anyone help me figure out where i am going wrong?
thank you.
This error it's related to database initialization...
You have to configure the database adapter in your application.ini:
resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "user"
resources.db.params.password = "password"
resources.db.params.dbname = "db"
Or you could also configure the database adapter in your bootstrap file:
$db = Zend_Db::factory("pdo_mysql", $params);
Zend_Db_Table::setDefaultAdapter($db);
Since the variable APPLICATION_PATH returns de full path to your application folder try naming your classes only
Model_DbTable_ModelName
i found out that the variable i was trying to access didn't start with an underscore and also capitalization issues with the models created was causing the problem.
Thank you all for helping
A few questions regarding the basics of Zend Framework 1.9.
i followed the quickstart guide, and basically, bootstrapping involves,
a. from index.php:
$ZEND_FRAMEWORK_LIB_PATH = '/appl/ZendFramework-1.9.7/library';
defined('APPLICATION_PATH') || define('APPLICATION_PATH', (realpath(dirname(__FILE__) . '/../application')));
defined('APPLICATION_ENV') || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));
set_include_path(implode(PATH_SEPARATOR, array((dirname(dirname(__FILE__)) . '/library'), $ZEND_FRAMEWORK_LIB_PATH, get_include_path(),)));
require_once 'Zend/Application.php';
$application = new Zend_Application(APPLICATION_ENV, (APPLICATION_PATH . '/configs/application.ini'));
$application->bootstrap()->run();
b. Then in the Bootstrap.php, i have
protected function _initAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array("namespace" => "Default_", "basePath" => dirname(__FILE__),));
return $autoloader;
}
protected function _initDoctype()
{
$this->bootstrap("view");
$view = $this->getResource("view");
$view->doctype("XHTML1_STRICT");
}
For a start, a few things i don't understand:
a. If a user access the site not via the default index.php, does that mean that bootstrapping (and indeed, all the code in the index.php including setting of environment etc, will be bypassed?)
b. There is no place that explicitly calls the Bootstrap's _initAutoload() or _initDoctype() methods. So when are these methods implicitly invoked?
c. Since in the index.php, i have already "passed in" the config file '/configs/application.ini' to the Zend_Application constructor, is there any way to retrieve the config entries elsewhere?
In my application, i have to work with different databases (so i can't just use resources.db.*). So in the same application.ini file, i have, e.g.
custdb.adapter = "PDO_MYSQL"
custdb.params.host = "localhost"
custdb.params.username = "username"
custdb.params.password = "password"
custdb.params.dbname = "custdb"
What's the best practice to manage the DB adapter?
a. Is it possible to (and should i) create the DB adapter in index.php OR Bootstrap.php and retrieve it elsewhere when needed (and how)?
b. Or is possible to (and should i) just retrieve the config entries elsewhere (how?) and instantiate the DB adapter as and when needed?
Thanks!
Here's a few answers.
2a. All request are redirected to index.php. This is done with mod_rewrite and specified in the .htaccess file.
2b. The bootstrap calls any method prefixed with _init. See Zend Framework - Theory of Operation
2c. Yes. Zend::Config. You could store an instance in Zend::Registry for easy access. Eg:
$config = new Zend_Config((APPLICATION_PATH . '/configs/application.ini'));
$application = new Zend_Application(APPLICATION_ENV, $config);
Zend_Registry::set('config', $config);
Check the API reference to see the constructors for these two classes.
I don't think the Quick start is that helpful. I'd recommend a getting a book. I enjoyed "Zend Framework 1.8 Web Application Development" by Keith Pope.
To answer question 3, ZF uses the Application Resource Plugin Zend_Application_Resource_Db to ingest the config and create a database adapter instance.
If your need for multiple databases is an environmental thing, you can easily namespace your DB params in your application.ini file.
[production]
resources.db.adapter = PDO_MYSQL
resources.db.params.host = localhost
resources.db.params.username = user
resources.db.params.password = pass
resources.db.params.dbname = production_db
[staging : production]
resources.db.params.dbname = staging_db
[development : production]
resources.db.params.dbname = development_db
In this example, we're setting up common info in the [production] section and overriding it for our staging and development environments. Which config is applied is controlled by the environment variable in your app's .htaccess
If you need to access multiple databases in a single application, then I would recommend rolling your own Application Resource Plugin, and creating some kind of structure to hold multiple connections.
It's not as difficult as it might seem. Read up on it here and create a subclass of of Zend_Application_Resource_ResourceAbstract. Using this class, you can easily grab resources.* in your config file using:
$this->getBootstrap()-getResource('mydb')`
You would then have access to your plugin via the bootstrap object:
$bootstrap->getPluginResource('mydb')
Hope that helps.
EDIT: I forgot to mention, if you have a resource plugin as part of your application.ini, the Zend_Application bootstrapper will automatically know to include it as part of the bootstrap proccess, so you don't need to define any _init() method in your bootstrap file. It's kind of magic like that.
Also, as far as storing an adapter instance, I'd probably just user Zend_Registry.
thanks for all your replies! It really helped my understanding of the concept of ZF.
i've also gone through the references and source codes to get a deeper understanding, and this is what i adopted:
In my application.ini i have:
custom.db.customers.adapter = "PDO_MYSQL"
custom.db.customers.params.host = "localhost"
custom.db.customers.params.username = "username"
custom.db.customers.params.password = "password"
custom.db.customers.params.dbname = "custdb"
Then, in my Bootstrap.php i have:
protected function _initCustomDbCustomers()
{
$config = $this->getOptions();
$cfgCustom = $config['custom'];
if (null != $cfgCustom)
{
$cfgCustomDb = $cfgCustom['db'];
if (null != $cfgCustomDb)
{
$cfgCustomDbCustomers = $cfgCustom['customers'];
if (null != $cfgCustomDbCustomers)
{
$resrcCustomDbCustomers = new Zend_Application_Resource_Db($cfgCustomDbCustomers);
return $resrcCustomDbCustomers
}
}
}
}
Of course, in my index.php, i call:
$application->bootstrap();
$application->run();
Then, in the controller where i need to get the DB adapter, i do:
$bootstrap = $this->getInvokeArg('bootstrap');
$resrcCustomDbCustomers = $bootstrap->getResource('customDbCustomers');
$adpCustomDbCustomers = $resrcCustomDbCustomers->getDbAdapter();
// Do Stuffs With DB Adapter
Is this a Good/Bad way to do things? And is there any pitfall i should watch for?
Thanks!