Using a Zend_Db Database connection - zend-framework

I'm trying to teach myself the Zend Framework. I have some extensive experience using custom-frameworks but have never used Zend. It's like trying to use a knife and fork with mittens on.
I've got a system up and running. A database connection is being created in the applition.ini file without errors.
The point I'm at is trying to use this connection to the database to execute basic SQL. The application.ini has the lines:
db.adapter = PDO_MYSQL
db.params.host = localhost
db.params.username = cpanel_dbuser
db.params.password = 123456
db.params.dbname = cpanel_dbname
I'm trying to connect to the database in my /public/index.php
$config = new Zend_Config_Ini(APPLICATION_PATH .
'/configs/application.ini', 'production');
$application->db = Zend_Db::factory($config->db);
Zend_Db_Table::setDefaultAdapter($db);
The error I get is:
Fatal error: Uncaught exception 'Zend_Db_Exception' with message 'Adapter name must be specified in a string' in /home/path/library/Zend/Db.php:226
Stack trace:
#0 /home/path/public/index.php(32): Zend_Db::factory(Array)
#1 {main} thrown in /home/path/library/Zend/Db.php on line 226
And if I print_r the Config Object
Zend_Config Object
(
[_allowModifications:protected] =>
[_index:protected] => 0
[_count:protected] => 2
[_data:protected] => Array
(
[adapter] => PDO_MYSQL
/* ... more stuff ... */
From my understanding of the tutorials & PDF's I'm working from, if I get this connection working I'll be able to do such fantastical amazements as the following from within a controller's indexAction
$data = $this->db->fetchAll(‘SELECT * FROM table’);
foreach ($data as $row) {
echo $row[‘table_fieldname’];
}
And then start writing models for the tables I have.
At this point, there's a pretty serious temptation to cut-the-corner and do this the way I already know how, but that completely defeats the purpose of learning to work within the framework.
Can anyone bridge the gap for me (or point me to a resource that can clear this up)?

In application.ini file inside config directory do
resources.db.adapter = PDO_MYSQL
resources.db.isDefaultAdapter = true
resources.db.params.host = localhost
resources.db.params.username = username
resources.db.params.password = pwd
resources.db.params.dbname = mydatabase
and whenever/wherever you need $db just do
$db = Zend_Db_Table::getDefaultAdapter()
this is the best way to do it.

public function ActionnameAction()
{
$params=array(
'host' =>'localhost',
'username' =>'username',
'password' =>'password',
'dbname' =>'database_name');
$db = Zend_Db::Factory('PDO_MYSQL',$params);
$sql="select * from table_name";
$result=$db->fetchAll($sql);
}

If I don't remember wrong, the adapters are case sensitive. You should use Pdo_Mysql. The exception you are receiving doesn't seems to be related to this though.

Related

how to use insert record function in moodle

I am trying to insert record into my database using moodle.
I am using version 1.9.19. i am trying the following code :
<?php
require_once('config.php');
require_once('uplo.php');
$mform = new uplo();
$mform->display();
if(isset($_POST['submitbutton'])){
$name = $mform->get_data('name');
$email = $mform->get_data('email');
$table='mdl_tet';
$res=insert_record($table, '$name','$email') ;
}
?>
But this is not working correctly. How to do that correctly.
Note : Why am using 1.9.19 means my client using this version so i cant change the version.
The insert_record() function takes two parameters - the name of the table (without the prefix) and an object containing the data to insert into the table.
So, in this case, you should write something like:
$ins = (object)array('name' => $name, 'email' => $email);
$ins->id = insert_record('tet', $ins);
OR:
$ins = new stdClass();
$ins->name = $name;
$ins->email = $email;
$ins->id = insert_record('tet', $ins);
(As an aside - make sure you turn on debugging - https://docs.moodle.org/19/en/Debugging - it will make your life a lot easier).

perl sybase connection error on x86pc-solaris

I have a Solaris system with x86 CPU, when I try to connect to sybase db with perl, i got the following error(the error was generated when I run the script in debug mode and step into function DBD::Sybase::db::_login at Sybase.pm in line 94)
ct_con_props(CS_PASSWORD) failed at /usr/local/lib/perl5/site_perl/5.8.8/i86pc-solaris/DBD/Sybase.pm line 94.
at /usr/local/lib/perl5/site_perl/5.8.8/i86pc-solaris/DBD/Sybase.pm line 94
DBD::Sybase::dr::connect('DBI::dr=HASH(0x8613a5c)', 'server=server1', 'user1, 'password1', 'HASH(0x86b4e5c)') called at /usr/local/lib/perl5/site_perl/5.8.8/i86pc-solaris/DBI.pm line 617
DBI::_ANON_/usr/local/lib/perl5/site_perl/5.8.8/i86pc-solaris/DBI.pm:679 called at /usr/local/lib/perl5/site_perl/5.8.8/i86pc-solaris/DBI.pm line 681
DBI::connect('DBI', 'DBI:Sybase:server=server1', 'user1, 'password1') called at ./test.pl line 28
DBI::CODE(0x83fcdd4)(/usr/local/lib/perl5/site_perl/5.8.8/i86pc-solaris/DBI.pm:618):
618: $user = '' if !defined $user;
from the message, it seems there is something wrong with the password? but I am sure the password was correct and the same code works very well on a Spark-solaris system, could anyone tell me what's wrong, or tell me how can I get into the function DBD::Sybase::db::_login($this, $server, $user, $auth, $attr)? looks like this function was in an .xs file, but I can not find where is it, and can not debug into it.
if I run the script withtout debug, i got the following error
ct_con_props(CS_PASSWORD) failed at /usr/local/lib/perl5/site_perl/5.8.8/i86pc-solaris/DBD/Sybase.pm line 94.
DBI connect('server=server1','user1’,...) failed: OpenClient message: LAYER = (1) ORIGIN = (4) SEVERITY = (6) NUMBER = (221)
Server server1, database
Message String: ct__string_extended_encryption: user api layer: internal common library error: error string not available
at ./test.pl line 28
Connect failed at ./test.pl line 28.
here is the code of sub connect in Sybase.pm
sub connect {
my($drh, $dbase, $user, $auth, $attr) = #_;
my $ifile = '';
my $server = $dbase || $ENV{DSQUERY} || 'SYBASE';
my($this) = DBI::_new_dbh($drh, {
'Name' => $server,
'Username' => $user,
'CURRENT_USER' => $user,
});
DBD::Sybase::db::_login($this, $server, $user, $auth, $attr)
or return undef;
return $this;
}
After sending a email to Michael Peppler(the module writer), I got the following answer and the issue was fixed.
The issue is the lib3p directory, which contains libraries that are loaded at run time directly by OpenClient, in particular for things like password encryption, etc.
This directory obviously needs to be in LD_LIBRARY_PATH, or be referenced in the default library search paths.
So basically, I need to add the path of OCS-15 folder to LD_LIBRARY_PATH

ZEND tralslations for addMultiOption text in Form for poEdit

I dont have an idea why translations are not working in with Zend_Form.
I would like to be able translate options for selects.
For now i have something like this:
my form class:
(...)
$this->translate = Zend_Registry::get('translate');
Zend_Form::setDefaultTranslator( Zend_Registry::get('translate') );
(...)
$select = new Zend_Form_Element_Select('select');
// $select->addMultiOption('0', $this->translate('Aktywny'));
$select->addMultiOption('0', $this->translate->_('Aktywny'));
$select->addMultiOption('1', 'Nieaktywny');
in my bootstrap file i have something like this:
protected function _initTranslate()
{
Zend_Loader::loadClass('Zend_Translate');
Zend_Loader::loadClass('Zend_Registry');
$translate = new Zend_Translate('gettext', APPLICATION_PATH.'/languages',
'browser',
array('scan' => Zend_Translate::LOCALE_FILENAME));
//changing language and setting it to session if changed
$session = new Zend_Session_Namespace('jezyk');
if(isset($session->language)) {
$translate->setLocale($session->language);
} else
$translate->setLocale('pl');
$registry = Zend_Registry::getInstance();
$registry->set('Zend_Translate', $translate);
}
and it works fine for controllers, phtml files and plugins where i call it by
$this->translate('string to translate');
and in plugins
$this->view->translate('string to translate');
but those methods won't work in form. It throws exception:
Warning: Exception caught by form: No entry is registered for key 'translate' Stack Trace: #0
to make it working as i wrote in comment just have to change line:
$this->translate = Zend_Registry::get('translate');
for
$this->translate = Zend_Registry::get('Zend_Translate');
cause i didn't saw that i'm getting wrong translate from registry. It should be Zend_Translate like in Bootstrap file, not translate as i did.
And this is solution for my problems with translate and now i can make translations in form files :)

Zend_Auth and Firebird DB

A short question for the PROs.
Is it possible to use Zend_Auth_Adapter_DbTable with ZendX_Db_Adapter?
I've tried this:
$adapter = new Zend_Auth_Adapter_DbTable(
Zend_Registry::get('db')
);
$adapter->setTableName('USERS')
->setIdentityColumn('username')
->setCredentialColumn('password')
->setIdentity('FOO')
->setCredential('BAR');
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate();
But it doesn't work.
ErrorMsg:
Catchable fatal error: Argument 1 passed to Zend_Auth::authenticate() must implement interface Zend_Auth_Adapter_Interface, none given, called in D:\xampp\htdocs\liquisales-online\application\controllers\IndexController.php on line 35 and defined in D:\xampp\htdocs\liquisales-online\library\Zend\Auth.php on line 115
Any hints?
Btw. ZendX_Db_Adapter ist registerd in application.ini
resources.db.adapter = Firebird
resources.db.params.dbname = "/var/db/liquisales.FDB"
resources.db.params.host = "127.0.0.1"
resources.db.params.username = sysdba
resources.db.params.password = masterkey
resources.db.params.adapterNamespace = "ZendX_Db_Adapter"
Okay, here is the right way to use Firebird DB with Zend_Auth.
At first we had to use capitol letters for column names.
Furthermore I've forgotten to pass the adapter.
Here's the right code.
$adapter = new Zend_Auth_Adapter_DbTable(
Zend_Registry::get('db')
);
$adapter->setTableName('USERS')
->setIdentityColumn('USERNAME')
->setCredentialColumn('PASSWORD')
->setIdentity($loginForm->getValue('kunummer'))
->setCredential($loginForm->getValue('passwd'));
$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($adapter);
it seems your adapter doesn't implement all the methods needed .... so you would have to code the authentication yourself.

Registering Zend Database Adapter in Registry

I am looking to register a reference to the main Database Adapter in the Registry during Bootstrapping so it can be used elsewhere in my site (specifically the Authorisation action).
I have implemented an ugly fix where i create a Database Table object and call the getAdapter() method on it and pass through that. However, this is a bad way of doing it and I would like it to be available via the registry.
Does anyone know how to do this? Any help or pointers in the right direction are appreciated!
I'm using Zend Framework 1.8.
If you're using Zend Framework 1.8+, and created your project with the command line tool, then it's as simple as registering your database settings in your application.ini config file.
resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "your.database.host"
resources.db.params.dbname = "database_name"
resources.db.params.username = "username"
resources.db.params.password = "password"
resources.db.isDefaultTableAdapter = true
If your database settings are preceded by resources.db you won't even need to do anything in your Bootstrap.php file because it will do it for you. Also, by setting the isDefaultTableAdapter setting to true, you can get an instance of your database adapter anywhere in your application.
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
Thanks for the replies. Ive decided to change the accepted answer and post the solution I finally used - which is insanely simple in the end!!
This is basically based on Dcaunt's comment...
In the bootstrap class..
protected function _initDb()
{
$resource = $bootstrap->getPluginResource('db');
$db = $resource->getDbAdapter();
Zend_Registry::set("db", $db);
}
Then access that elsewhere with...
$dbAdapter = Zend_Registry::get("db");
Thanks for the help and hopefully this helps someone else.
Your missing the best thing :)
If you use the Zend_Db_Table models (you should be) etc then you can set up a default adaptor - this way when you instantiate a model the DB connection it taken care off - this way you dont really need to save it in the registry or bother about connection before running a query through the model.
I do save it in the registry for later use if needed though - but I may remove this
protected function _initDB()
{
// Check that the config contains the correct database array.
if ($this->_config->db) {
// Instantiate the DB factory
$dbAdapter = Zend_Db::factory($this->_config->db);
// Set the DB Table default adaptor for auto connection in the models
Zend_Db_Table::setDefaultAdapter($dbAdapter);
// Add the DB Adaptor to the registry if we need to call it outside of the modules.
Zend_Registry::set('dbAdapter', $dbAdapter);
}
}
My 2 cents...
How to grab the default DB Adapter:
From Bootstrap:
<?php
$dbResource = $this->getPluginResource('db');
db = $dbResource->getDbAdapter();
var_dump($db);
?>
From a Controller there are two methods:
<?php
// Method 1
$bootstrap = $this->getInvokeArg('bootstrap');
$dbResource = $bootstrap->getPluginResource('db');
$dbAdapter = $dbResource->getDbAdapter();
var_dump($dbAdapter);
// Method 2
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
var_dump($dbAdapter);
?>
Check the zend-documentation at :
15.5.3.3. Storing a Database Adapter in the Registry
http://framework.zend.com/manual/en/zend.db.table.html
$db = Zend_Db::factory('PDO_MYSQL', $options);
Zend_Registry::set('my_db', $db);
// Later...
$table = new Bugs(array('db' => 'my_db'));
something like that you're looking for?
Edit:
to load your configuration from an ini-file, use:
parse_ini_file($inifile)
;configuration.ini
host = 127.0.0.1
user = username
password = blabla
;yourfile.php
$options = parse_ini_file('configuration.ini');
$db = Zend_Db::factory('PDO_MYSQL', $options);
I have a method in my bootstrap to add the adapter to the registry. I'd prefer a cleaner solution, but it works:
protected function _initRegistry(){
$this->bootstrap('db');
$db = $this->getResource('db');
$db->setFetchMode(Zend_Db::FETCH_OBJ);
Zend_Registry::set('db', $db);
}
Here is what i do:
Inside the bootstrap:
define('CONFIG_FILE', '../config/general.ini');
define('APP_MODE', 'development');
Inside the Initializer:
/**
* Initialize data bases
*
* #return void
*/
public function initDb ()
{
$options = Zend_Registry::get('conf');
$db = Zend_Db::factory($options->database);
$db->query(new Zend_Db_Expr('SET NAMES utf8'));
Zend_Registry::set('db', $db);
}
public function initConfig ()
{
if (file_exists(CONFIG_FILE) && is_readable(CONFIG_FILE)) {
$conf = new Zend_Config_Ini(CONFIG_FILE, APP_MODE);
Zend_Registry::set('conf', $conf);
} else {
throw new Zend_Config_Exception('Unable to load config file');
}
}
And finaly my config file looks like this:
[production]
database.adapter = pdo_Mysql
database.params.host = db.example.com
database.params.username = dbuser
database.params.password = secret
database.params.dbname = dbname
; Overloaded configuration from production
[development : production]
database.params.host = localhost
database.params.username = root
database.params.password =
Take a look at:
Zend_Db::Factory()
Zend_Config_Ini
Zend_Registry
If you are using Zend Framework 1.8 just do something like this in your controller/action:
class CreateorderController extends Zend_Controller_Action
{
public function testAction()
{
//more code
$users_obj = new Default_Model_Users(); //this would load the model using the Default namespace
//more code
}
}
My Defaul_Model_Users class would look something like this:
<?php
/**
* application/models/Users.php
*/
class Default_Model_Users extends Zend_Db_Table
{
protected $_table;
public function getTable()
{
if(null === $this->_table) {
$this->_table = new Default_Model_DbTable_Users();
}
return $this->_table;
}
public function fetchAll()
{
$result = $this->getTable()->fetchAll();
return $result;
}
}
And the part of the model which "interacts" directly with the database tables is found inside DbTable directory will look like this:
<?php
/**
* application/models/DbTable/Users.php
*/
class Default_Model_DbTable_Users extends Zend_Db_Table_Abstract
{
/** Table name */
protected $_name = 'users';
public function init()
{
$this->_db->setFetchMode(Zend_Db::FETCH_OBJ);
}
}
Then I would have the same application.ini generated by Zend Framework with this small addition:
resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "localhost"
resources.db.params.dbname = "mydb"
resources.db.params.username = "root"
resources.db.params.password = "password"
That is how I did without without having to change the bootstrap files.
I didn't want to use the registry to store an object that I should be able to access, so I did a little digging. It turns out that the bootstrap is registered as the front controller parameter "bootstrap", which is accessible from any of your controllers as explained in this manual page for Zend_Application.
So in your controller classes you can get the db adapter that has been defined in your ini file like this:
$bootstrap = $this->getInvokeArg('bootstrap');
$resource = $bootstrap->getPluginResource('db');
$db = $resource->getDbAdapter();