How Can I Read the DB Configuration Settings From a Cake Shell? - cakephp

I would like to write a cake shell to do a nightly backup of my database using mysqldump. I could do this as a shell script, but if I can cram it into a CakePHP shell, then I will get the added benefit of it working across both the development and live server, if I can get it to automagically read my database config settings. I will cron the cake shell and have some peace-of-mind knowing that I have frequent backups of my DB.
In my shell I'm trying to build up a string which starts with "mysqldump --user=" and I'd like to get the username from app/config/database.php. How can I get at the data in database.php?

In cake 2.1 the format has changed to:
App::uses('ConnectionManager', 'Model');
$dataSource = ConnectionManager::getDataSource('default');
$username = $dataSource->config['login'];

The following snippet should do the trick:
App::import('Core', 'ConnectionManager');
$dataSource = ConnectionManager::getDataSource('default');
$username = $dataSource->config['login'];

In CakePHP 3.x the format has changed to -
use Cake\Datasource\ConnectionManager;
$source = ConnectionManager::get('default');
debug($source); #Debugging the result
Result :
object(Cake\Database\Connection) {
'config' => [
'password' => '*****',
'username' => '*****',
'host' => '*****',
'database' => '*****',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
'quoteIdentifiers' => false,
'log' => false,
'url' => null,
'name' => 'remote'
],
'driver' => object(Cake\Database\Driver\Mysql) {
'connected' => false
},
'transactionLevel' => (int) 0,
'transactionStarted' => false,
'useSavePoints' => false,
'logQueries' => false,
'logger' => null
}
Get the Result :
debug($source->config()); #Accessing the result
Result :
[
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
'username' => 'username',
'password' => 'password',
'database' => 'database',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
'quoteIdentifiers' => false,
'log' => false,
'url' => null,
'name' => 'remote'
]

Just for sharing.
For any cakephp project, if using php as cronjob or command line to do large data processing I would build a standalone php script without cakephp, the reason for doing this because cakephp is slow (e.g. read & process 100K records).
To make my life simple I put all my standalone scripts under app/Vendor/myscripts/ (e.g: app/Vendor/myscripts/process.php)
below also the basic code to make sure you use the same database settings in standalone script with cakephp (tested with MySQL)
require_once '/XYZ/app/Config/database.php';
$database = new DATABASE_CONFIG;
try{
$dblink = new PDO('mysql:host='.$database->default['host'].';dbname='.$database->default['database'], $database->default['login'], $database->default['password'], array(PDO::ATTR_PERSISTENT => false));
$dblink->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dblink->exec('SET CHARACTER SET '.$database->default['encoding']);
} catch (Exception $e) {
die('DB Error'. $e->getMessage());
}

Example in controller, Change multi DB for DataSources in CakePHP 2.5.x
App::uses('AppController', 'Controller');
class DemoController extends AppController {
public $uses = array('AppModel', 'GVA21', 'GVA01', 'GVA14', 'GVA24' );
public function test_dbs(){
$this->autoRender=false;
// Load ConnectManager
App::uses('ConnectionManager', 'Model');
// DataSource ['default']
$MDM = $this->GVA14->find('count');
echo "MDM.GVA14\n<br>";
debug($MDM);
// Get DataSource Config DB ['default'] and ['SRL']
$confDeafult = ConnectionManager::$config->default;
$confSrl = ConnectionManager::$config->SRL;
// Change DataSource ['SRL']
ConnectionManager::drop('default');
ConnectionManager::create('default',$confSrl); //<== Is permanet change Find All models Down
// $this->GVA01->setDataSource('SRL'); //<== Is temp change Find model
echo "SRL.GVA14\n<br>";
$SRL = $this->GVA14->find('count');
debug($SRL);
$SRL = $this->GVA01->find('count');
echo "SRL.GVA01\n<br>";
debug($SRL);
$SRL = $this->GVA21->find('count');
echo "SRL.GVA21\n<br>";
debug($SRL);
// Change to DataSource ['default']
debug(ConnectionManager::drop('default'));
ConnectionManager::create('default',$confDeafult); //<== Is permanet change Find All models Down
//$this->GVA01->setDataSource('default'); //<== Is temp change Find model
$MDM = $this->GVA01->find('count');
echo "MDM.GVA01\n<br>";
debug($MDM);
$MDM = $this->GVA21->find('count');
echo "MDM.GVA21\n<br>";
debug($MDM);
////FIN
exit('FIN');
}

Related

How to create database schema (table) in Laravel?

I'm new to Laravel.I'm trying to create database in Laravel. I tried in console with:
Schema::create
But it's giving 'command not found'. What should I install or how to create database?
my working example:
create new artisan command:
php artisan make:command mysql
the content of App\Console\Commands\mysql.php :
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class mysql extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'mysql:createdb {name?}';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Create a new mysql database schema based on the database config file';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$schemaName = $this->argument('name') ?: config("database.connections.mysql.database");
$charset = config("database.connections.mysql.charset",'utf8mb4');
$collation = config("database.connections.mysql.collation",'utf8mb4_unicode_ci');
config(["database.connections.mysql.database" => null]);
$query = "CREATE DATABASE IF NOT EXISTS $schemaName CHARACTER SET $charset COLLATE $collation;";
DB::statement($query);
config(["database.connections.mysql.database" => $schemaName]);
}
}
then run: (schema_name is optionally)
php artisan mysql:createdb schema_name
First you have to set database name,username and password in database.php in config folder.it look like
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => storage_path('database.sqlite'),
'prefix' => '',
],
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'news'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
],
],
if you are using xampp then right click on your project folder and click on use composer here
then run following command
php artisan migrate:install
and you can create table like
php artisan make:migration create_users_table
Migration Structure
A migration class contains two methods: up and down. The up method is used to add new tables, columns, or indexes to your database, while the down method should simply reverse the operations performed by the up method.
Within both of these methods you may use the Laravel schema builder to expressively create and modify tables. To learn about all of the methods available on the Schema builder, check out its documentation. For example, let's look at a sample migration that creates a flights table:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateFlightsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('airline');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('flights');
}
}
To know all artisan command run following command
php artisan
for more read following document http://laravel.com/docs/5.1/migrations
Database setup in Laravel
open .env file on root
example :-
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=dbname
DB_USERNAME=root
DB_PASSWORD=password
Now run command
php artisan migrate:install
php artisan make:migration users // for creating new table
If you want to create model with artisan do it this way:
php artisan make:model ModelName

Cache-issue changing Cakephp database settings on the fly

I'm building a Website in Cakephp with variable databases.
I did this with the following code:
CONTROLLER:
$db_host = $DB_SET['Project']['db_host']; //From other database
$db_user = $DB_SET['Project']['db_user'];
$db_pass = $DB_SET['Project']['db_pass'];
$db_database = $DB_SET['Project']['db_database'];
ConnectionManager::create("client_db", array(
'datasource' => 'Database/Mysql',
'driver' => 'mysql',
'persistent' => false,
'host' => $db_host,
'login' => $db_user,
'password' => $db_pass,
'database' => $db_database,
'prefix' => '',
'encoding' => 'UTF8',
'port' => '',
));
$DB_LINE = $this->Page->findPage('3');
MODEL:
class Page extends Model {
public $useDbConfig = 'client_db';
function findPage($pagenr) {
$page = $this->find('first', array(
'conditions' => array (
'Page.id' => $pagenr)
));
return $page;
}
}
Now I also need to change of tables in the database on the Fly.
I do this using(Controller):
$tbl_current = array('tbl_cheques', 'tbl_wishes');
$this->Modelname->useTable = $tbl_current[$pageid]; //Getting the pageID from an url parameter.
Everything works fine, only if I don't wait a while before clicking another page I get this error:
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Page.fqlkdf' in 'field list'
This because Cake still have the previous table in his Cache.
If I wait a minute and then I change the page it works fine.
Any suggestions for this problem?
Thanks in advance,
AƤron
Like you said, the table info is cached. So you just need to remove that cache:
Cache::clear(false, '_cake_model_');
Or, you can just temporarily disable cache
Configure::write('Cache.disable', false);

CakePHP Config File

I was wondering is there a way i can set up the config where i can have two database entries that work when the environment is Local and when on Server.
I had come across a solution long time back on doing the switch through the code. Not able to find it now. How do you guys do it ?
I have a setup with local config files. I add the following lines at the bottom of app/config/core.php:
if(file_exists(ROOT.'/app/config/core.local.php')) {
include_once(ROOT.'/app/config/core.local.php');
}
In core.local.php I can override all the settings that differ on the local machine. The same goes for database.php.
I use a config class which does exactly that:
http://www.dereuromark.de/2010/08/17/development-vs-productive-setup
Recently I rewrote it for 2.0 as a plugin version.
It now takes care of test environments and cuts down the number of lines of configuration you will have to write:
http://www.dereuromark.de/2012/02/25/dynamic-database-switching/
I think it based on IP
at local environment IP is 127.0.0.1
and at live environment IP is never 127.0.0.1
My view
Thanks
check with the lib/Cake/Utility/String.php see the function named
public static function uuid()
cheers
Thanks again
This worked
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'username',
'password' => 'password',
'database' => 'database_name',
'prefix' => '',
//'encoding' => 'utf8',
);
public $live = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'db.HOST.net',
'login' => 'username',
'password' => 'password',
'database' => 'database_name',
'prefix' => '',
//'encoding' => 'utf8',
);
public function __construct(){
if (isset($_SERVER) && isset($_SERVER['SERVER_NAME'])) {
if (strpos($_SERVER['SERVER_NAME'], 'localhost') === false) {
$this->default = $this->live;
}
}
}
}

cakephp dynamic db connection

I have an application where each subscriber gets their own 'app' folder within their own url eg.
www.domain.com/1234 subscriber1
www.domain.com/2345 subscriber2
now the db connection is configured in a class in config/database.php. I want to be able to change the database used based on the url (eg. /1234 = db_1234).
How would I achieve this?
Thanks
BTW I am using CakePHP 2.0
My previous solution was a load of rubbish. So I thought about attacking the problem from a different angle. My DATABASE_CONFIG class (/app/Config/database.php) now looks like this:
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => '127.0.0.1',
'login' => 'xxxx',
'password' => 'xxxx',
'database' => 'xxxx',
'prefix' => '',
'encoding' => 'utf8',
);
public $site_one = array(
'datasource' => 'Database/Mysql',
'host' => '127.0.0.1',
// ...
);
public $site_two = array(
'datasource' => 'Database/Mysql',
'host' => '127.0.0.1',
// ...
);
public function __construct()
{
if (strpos(env('HTTP_HOST'), 'site_one') !== false) {
// use site_one database config
$this->default = $this->site_one;
// elseif site_two
} elseif (strpos(env('HTTP_HOST'), 'site_two') !== false) {
// use site_two database config
$this->default = $this->site_two;
}
}
}
When Cake loads, the construct is now called automatically, and this sets the 'default' database connection dependent on the host.
Ah I got it now,
I thought DATABASE_CONFIG was called statically so didn't think to use the construct.
www.domain.com/12345678
function __construct() {
// get folder
if(substr(php_sapi_name(), 0, 3) == "cli") {
$j = explode("/", $_SERVER['PWD']);
$this->default['database'] = "sa_".$j[count($j)-1];
} else {
$j = explode("/", $_SERVER['REQUEST_URI']);
$this->default['database'] = "sa_".$j[1];
}
}
but commandline bake must be done in folder eg. 12345678/

Zend database connectivity

I used this in my UserController
require_once 'Zend/Controller/Action.php';
AND
public function processAction()
{
$params = array('host' =>'localhost',
'username' =>'root',
'password' =>'',
'dbname' =>'zend'
);
$DB = new Zend_Db_Adapter_Pdo_Mysql($params);
$request = $this->getRequest();
$data = array('first_name' => $request->getParam('first_name'),
'last_name' => $request->getParam('last_name'),
'user_name' => $request->getParam('user_name'),
'password' => md5($request->getParam('password'))
);
$DB->insert('user', $data);
$this->view->assign('title','Registration Process');
$this->view->assign('description','Registration succes');
}
Which displayed following error. I do not have the php.ini access.
Fatal error: Class 'Zend_Db' not found in D:\xampp\xampp\htdocs\zend-test\zend-demo\application\controllers\UserController.php on line 42
i.e. on this line
$params = Zend_Db::factory('Pdo_Mysql', array(
'host' => 'localhost',
'username' => 'root',
'password' => '',
'dbname' => 'zend'
));
Thanks in advance!
Mangesh
Maybe this will help.
Tutorial on how to setup a working Zend framework
http://usingzendframework.blogspot.com/2007/01/setting-up-zend-framework.html
You need to include all of the Zend libraries you use - not just
equire_once 'Zend/Controller/Action.php';
Also, you need to do what Jurka specified - a much better and cleaner practice.

Resources