Is there any dynamic way to put sqlite database connection instead of using sqlite:f:\\wamp\\www\\qdr\\protected\\data\\testdrive.db in main.php ?
'db'=>array(
'connectionString'=>'sqlite:f:\\wamp\\www\\qdr\\protected\\data\\testdrive.db',
),
Sql lite is about a single file so you can keep it like this. No dynamic needed. I am sure you are using wamp. Just keep it like this. This is the best solution for you. When you move the project to live server then change accordingly. Sqlite is a single file so do not bother that much.
It depends on what you understand under the vague term dynamic. But you could for example create your custom DBConnection class and override init() there:
class DbConnection extends CDbConnection
{
public function init()
{
// Set $this->connectionString to whatever you want, maybe
// $this->connectionString = 'sqlite:'.dirname(__FILE__).'/../data/testdrive.db';
parent::init();
}
}
You can use this component as db component if you add
'class' => 'DbConnection',
to your main.php.
Note, though, that the init() method is only called the first time when the db component is accessed. So whatever you set as connectionString there will be used for the current request.
Related
I'm new to CodeIgniter and currently in my project I have several Models, loaded by several Controllers, which need to work with the database.
My question is - can I call $this->load->database() in just one place for the entire project, or should I do it in each method in my Models?
Thanks
In your autoload.php which is located in /application/config/autoload.php in which you see
$autoload['libraries'] array just add
$autoload['libraries'] = array('session', 'database','other_libraries');
If your project scope involves the database interaction you should use the autoload while including in each function would be a headache for you
Hope it makes sense
You have three choices (that I can think of).
If you require it almost everywhere in your project, use the
/application/config/autoload.php file, in which you'll find the
following statement:
$autoload['libraries'] = array();
which you can change to
$autoload['libraries'] = array('database');
This is the easiest method, but it does add overhead since the database class will be loaded even when you do not require it.
If you find that you need to use it for almost every method in a particular model you can call $this->load->database(); in the constructor of that particular model, for example:
class Forums_model extends CI_Model{
function __construct()
{
// Call the parent constructor
parent::__construct();
$this->load->database();
}
function get_records()
{
$this->db->get('table');
//this now works in every method in this model
}
}
which will make the database class available to every method in that model. This is a more efficient option than the second and not as tedious as the third, probably making it the most balanced option.
You can also, of course, choose to load it in every method that requires it using $this->load->database(); This adds the least overhead, theoretically making it the most efficient. However, doing this is very tedious.
All three will work, it's your choice whether you want it to be easy, or efficient. (My personal recommendation is choice 2)
If only some of your pages require database connectivity you can manually connect to your database by adding this line of code
$this->load->database();
in any function where it is needed, or in your class constructor to make the database available globally in that class.
The "auto connect" feature will load and instantiate the database class with every page.just
add the word 'database' to the library array, as indicated in the following file:
application/config/autoload.php
http://ellislab.com/codeigniter/user-guide/database/connecting.html
I know this is not the best of all methods, but since you are beginner.. you just call load data base $this->load->database() in that method just above the code where your database related query begins.. just suppose $this ->load->database(); is exactly the same thing for you as you were using include_once('connection.php') this script in you simple php script (without CI).
I've just started learning CodeIgniter, and I'm following this authentication tutorial by nettuts+. I did not understand one thing in it:
He added the following constructor code in the Welcome controller, which basically can be accessed only if the Session has variable username, otherwise it will redirect to admin controller.
function __construct()
{
session_start();
parent::__construct();
if ( !isset($_SESSION['username'])){
redirect('admin');
}
}
He said:
If you have multiple controllers, then
instead of adding the above code in
every controller, you should Create a
new library, which extends the
controller you will paste the code in,
and autoload the library into
project. That way this code runs
always when a controller is loaded.
Does it mean, I should
Create a file in application/libraries (eg. auth.php)
Paste this code in the auth.php
.
if ( !isset($_SESSION['username'])){
redirect('admin');
}
Now how to autoload this library and make it run every time a controller is loaded as he said?
Thanks
1) to autoload a library, just add it to the array in the file application/config/autoload.php, look for the 'library' section and paste the name of the library(without extension) there, as an element of the array.
$autoload['libraries'] = array ('auth');
2) I suggest you use the native session handler (session library), which works pretty well and avoids you to use php $_SESSION. You set a width $this->session->set_userdata(array('username' => 'User1', 'logged' => 'true'), and then you retrieve the values with $this->session->userdata['logged'], for ex.
Works like a charm and don't have to call session_start() and so on. Go check the help because it's really really clear on that.
3) As for your problem, I'll go, instead, for 'hooks'. There are different hooks, depending on their 'position', i.e. the moment in which you're calling them.
You can use, for ex.. the 'post_controller_constructor', which is called after controller initialization but BEFORE the methods, so it's in a midway between the constructor and the actual method. I usually insert this controls here.
You define hooks in application/config/hooks.php, and give them an array:
$hook['post_controller_constructor'] = array(
'class' => 'Auth',
'function' => 'check',
'filename' => 'auth.php',
filepath' => 'hooks',
'params' => array()
);
Anyway, for all these needs, the docs are pretty clear and straightforward, I suggest you read about hooks and session and you'll see everything gets much clearer!
The other way to do this. This is what he means in tutorial.
Create a library called MY_Controller in your application/libraries folder and extend it from CI_Controller:
Class MY_Controller extends CI_Controller {
public function __construct()
{
parent::__construct();
// do the stuff you want to execute on every page.
// like auth.
}
}
Autoload the auth class in autoload.php config file. There is no need to autoload MY_Controller CodeIgniter will automaticly recognise it and run it. You can also load the Auth library within MY_Controller
Extend your controllers with MY_Controller class. (Not CI_Controller)
Extending your controller will give to more control of your project. You can add extra methods to use everywhere on your project.
For more information about extending native libraries of CodeIgniter check Creating Libraries: CodeIgniter.
Add the new library to the autoload library array in config/autoload.php.
$autoload['libraries'] = array ('database', 'session', 'auth');
Then when you want to call the function in controller constructors use $this->auth->function_name();.
You may want to make it a hook if there's a lot of repeat functionality that you don't want to call in every single constructor.
I'm fairly new to OOP PHP and am having trouble with getting a couple of classes to work nicely together. I'm using a database abstract class to do all the grunt work of talking to the database and that is all fine, and I can extend it with another class with the methods to make specific actions. The database class has an include_once to read in the config settings for the database.
Where I am confused is if I need to use a 2nd class to access the database on the same page, I need to reference a 2nd config file that has the same settings.
Example: I have a products class for a site I'm building and it is working fine. I wanted to use a 2nd class to control the actual shopping cart side of things, but when I try and extend the database class with the Cart class the page fails unless I override which config file it needs to reference.
Why do I need separate config files for each class and is there a way around this? It seems silly that I should need as many config files as there are classes that interact with the database.
Thanks for your help.
Jon
* Extra Info *
Sorry guys, Everything is in the same database. Here is some sample code.
All config files are like this:
$DB_HOST = "localhost";
$DB_USER = "abcdef";
$DB_PASS = "123456";
$DB_DATABASE = "newdb_name";
then I override the config file which it needs to pull in but doing this in the sub classes:
function __construct()
{
$this->conffile = "db_conf1.php";
parent::__construct();
}
and change the $this->conffile for each new sub class.
I'm using a database abstract class to do all the grunt work of talking to the database and that is all fine, and I can extend it with another class with the methods to make specific actions. The database class has an include_once to read in the config settings for the database.
This is a bad design. If you need to use two of these classes together in the same script, you're going to end up w--
Where I am confused is if I need to use a 2nd class to access the database on the same page
Phew, you got it already.
You generally only want one database connection per page. This generally means only one database object. You have two good options in PHP to deal with this.
The first has a fancy name: "Dependency Injection." In DI, your objects require some external resource to work. They receive this resource during construction.
In other words, you pass your database object in the constructor.
class Foo {
protected $db;
public function __construct($other, $args, $db) {
$this->db = $db;
}
}
This way, you still get the convenience of referencing the database from within your object without having to make it too intermingled.
The other option also has a fancy name: the "Registry Pattern." Registries act as gateways to "well-known" classes and instances. They're basically look-up tables, allowing you to make your program depend on data that will be present in the Registry rather than hard-coding class names or using globals.
Or, in other words, it's just a global hash with a special name.
Doing it right requires a class. This blog post from 2009 is an interesting starting point because it deals exactly with the problem of what to do with a database adapter. I'll omit example code here, as the blog post does a decent job of explaining itself.
There is a third option, of course, and it's the worst, yet most common in PHP land: assigning the database object to a global, then referencing the global as needed. It's quick, it's dirty, it usually works... but can make maintenance difficult, and can make automated testing impossible to do correctly. Don't do it.
You should remove the dependency on the config file from the database class and pass the variables you need into the database constructor e.g.,
class Database {
public function __construct($host, $user, $pass, $dbname, $port) {
// create connection
}
//...
}
Put the info for both your databases into one config file and create your database objects like this:
include_once 'config.php';
$db1 = new Database($host1, $user1, $pass1, $dbname1, $port1);
$db2 = new Database($host2, $user2, $pass2, $dbname2, $port2);
Is there a helper method/object/methodology for getting a reference to a Zend_Application's config resource?
I know I can do something like
$config = new Zend_Config_Ini($file, $environment);
but that's going to reload/parse the config file. I'm looking for a way to peek at the given configuration value for a running Zend_Application.
The larger issue I'm trying to solve is I want a Zend_Queue to use the same database settings as my default database resource. If there's a more "Zend Like" way of achieving this other than "get reference to config, read resource values" please feel free to share that as well!
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
public function run()
{
// make the config available to everyone
$config = $this->getOptions();
Zend_Registry::set('config', new Zend_Config($config));
parent::run();
}
}
Zend_Queue
there is code in Zend_Queue_Adapter_Db __construct if (isset($this->_options['dbAdapter'])) so u can do thomething like this
new Zend_Queue_Adapter_Db(array('dbAdapter' => Zend_Db_Table::getDefaultAdapter()));
because standart Zend_Application_Resource_Db can use config option resources.db.isDefaultTableAdapter = true
or u can put db adapter in registry and get it from there at any place
Zend_Controller_Front::getInstance()->getParam('bootstrap')->getOptions()
I would like to know where is the best place to set my db object with my model.
Should I hard coded it since my model should be designed for one project, so i set it inside my constructor or wherever i do initialization ?
or
Should I pass my db object to my constructor when instancing my object ?
What is the best way, i mean from experimented users, and efficient that'll give me more confort to use ?
Couple of things:
Most PHP projects that utilize a database connection represent that database using a Singleton pattern, if you aren't sure what this is, read up on it.
Typically I define my database connections in a configuration file which can easily be changed between environments (development, stage, production).
I'll then instantiate my database connection in a bootstrap file using the aforementioned Singleton pattern and configuration file.
My models will typically completely abstract the database/table data store, for each model I'll do something like this:
bootstrap.php
$config = load_config_data(ENVIRONMENT);
Db::setDefaultAdapter($config['database']);
Model/Table/User.php
class Table_User extends Db_Table
{
// Table name
protected $_name = 'user';
/* Do a bunch of database specific stuff */
}
Model/User.php
class User extends Model
{
public function updateUsername($userid, $username)
{
// Uses default adapter, Singleton pattern!
$table = Db::loadTable('user');
$table->update(
array('username'=>$username),
Db::quoteInto('userid = ?', $userid)
);
}
}
This is pretty much an introduction to the Model in the Zend Framework MVC, I would check it out for some ideas on how to organize your code (or save yourself some trouble and actually use the framework.)
For testability, you should pass it into the constructor rather than hard coding it. This helps you to write unit test because you can mock your DB object.
I would not hard code it, even if the code is never used for another project simply moving from a test database to a live database may require locating and changing the code in the model class. That would be far better placed in some kind of configuration file.
Personally, I would have the db object defined in whatever you use as a bootstrap - and then have the model(s) use that single object.