How to debug eloquent queries executed in Codeigniter - event-handling

I'm using Eloquent 5.* on my CodeIgniter3.1.1 project, Everything works fine however i want to check the queries executed when a request is processed,
After some googling i came accross Using Eloquent ORM inside CodeIgniter with added Query Logging and having CI Profiler enabled i see "No Queries Executed",
my database.php configuration for Eloquent looks as below
//Eloquent ORM database connection
use Illuminate\Database\Capsule\Manager as Capsule;
$capsule = new Capsule;
$capsule->addConnection(array(
'driver' => 'mysql',
'dsn' => 'mysql:host=localhost; dbname=communit_iwa_test charset=utf8;',
'host' => $db['default']['hostname'],
'database' => $db['default']['database'],
'username' => $db['default']['username'],
'password' => $db['default']['password'],
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => $db['default']['dbprefix'],
));
$capsule->setAsGlobal();
$capsule->bootEloquent();
$events = new Illuminate\Events\Dispatcher;
$events->listen('illuminate.query',function($query, $bindings, $time,$name) {
// Format binding data for sql insertion
foreach ($bindings as $i => $binding) {
if ($binding instanceof \DateTime) {
$bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
} else if (is_string($binding)) {
$bindings[$i] = "'$binding'";
}
}
// Insert bindings into query
$query = str_replace(array('%', '?'), array('%%', '%s'), $query);
$query = vsprintf($query, $bindings);
// Add it into CodeIgniter
$db = & get_instance()->db;
$db->query_times[] = $time;
$db->queries[] = $query;
});
$capsule->setEventDispatcher($events);
/* End of file database.php */
/* Location: ./application/config/database.php */
Your Help is appreciated in advance

To view executed eloquent queries usegetQueryLog() method of the classIlluminate\Database\Capsule\Manager;
in short
Include Illuminate\Database\Capsule\Manager class in your controller or model as use Illuminate\Database\Capsule\Manager as Capsule;
use Capsule::getQueryLog() method to view an array of all queries executed in Eloquent ORM

Related

Fuel PHP - to_array() method and multiple belongs_to relationships and eager loading

I am attempting to migrate some legacy data models/schemas to a fuel API, and have run into an odd issue with the to_array() method on a model that has two $_belongs_to properties.
When I load the model without the to_array() method, I properly receive both related items with eager loading, but as soon as I pass them through this function to convert the data to make it digestable by the new API, it will strip out the second $_belongs_to property. If I re-order the props in the $belongs_to array, it will show whichever item is first in the array.
My question is, how can I convert this data to an array without losing the second relationship?
Here are some cleaned up examples for ease of reference:
Transaction Model:
protected static $_belongs_to = array(
'benefactor' => array(
'key_from' => 'from_user_id',
'model_to' => 'Model\\Legacy\\User',
'key_to' => 'id',
),
'user' => array(
'key_from' => 'user_id',
'model_to' => 'Model\\Legacy\\User',
'key_to' => 'id',
),
);
Transaction Controller:
$result = array();
$id = $this->param('id');
if (!empty($id)) {
$transaction = Transaction::find($id, array('related' => array('user', 'benefactor',)));
if (!empty($transaction)) {
// Works -- both benefactor and user are returned
$result['transaction_works'] = $transaction;
// Does not work -- only the benefactor is returned
$result['transaction_doesnt_work'] = $transaction->to_array();
}
}
return $this->response($result);
For any googlers looking for help on this issue, I was seemingly able to return all relationships by simply executing the to_array() method before setting the return/results variable:
$result = array();
$id = $this->param('id');
if (!empty($id)) {
$transaction = Transaction::find($id, array('related' => array('user', 'benefactor',)));
if (!empty($transaction)) {
$transaction->to_array();
$result['transaction_works'] = $transaction;
}
}
return $this->response($result);
Good luck!

How to use the "LIKE" statement in mongodb cakephp

I am using ICHIKAWAY's mongodb driver for cakephp.
One thing that I don't really get is how to perform a "LIKE" statement in cakephp using MONGODB.
I tried this statement:
$users = $this->User->find('all', array('conditions' => array('data_type' => 'user', 'profile.firstname LIKE' => '%'.$string)));
but its not working since "LIKE" is an mysql function.
Thanks for the suggestions.
Use MongoRegex
Mongo DB has a LIKE operator - it's simply a regular expression, to use it:
$users = $this->User->find('all', array(
'conditions' => array(
'data_type' => 'user',
'profile.firstname' => new MongoRegex("/$string/i")
)
));
There's an SQL Compatibilty behavior
The Mongodb driver contains a behavior providing sql syntax compatibility. To use it, simply make sure your model is using this behavior:
class User extends AppModel {
$actsAs = array(
'MongoDB.SqlCompatible'
)
}
And then you can use your query exactly as it appears in the question:
$users = $this->User->find('all', array(
'conditions' => array(
'data_type' => 'user',
'profile.firstname LIKE' => '%'.$string
)
));

how best to use two databases in cakephp 2.3?

I am using two databases in an application that I am creating in cakephp 2.3. A mysql database, which typically configured, and another database nosql (MongoDB), I use this way for example:
$connection = new Mongo('localhost');
$db = $connection->compras;
return $db->anuncios->insert($dados);
can I use this way?
about security ..., what possible problems that you guys realize to use mongo database that way?
You've to setup environment in the app/Config/Core.php file which mean which database you want to use in which mode i.e. Production, Development, staging etc with below
if(env('HTTP_HOST')):
switch (env('HTTP_HOST')) {
case "example.com":
case "www.example.com":
define('DEVELOPMENT_MODE', false); // Suppose you're using production for Mysql databse
break;
case "development.example.com":
define('DEVELOPMENT_MODE', true); // Suppose you're using development for MongoDB
break;
default:
define('DEVELOPMENT_MODE', true);
break;
}
After that you've to use DEVELOPMENT_MODE variable in the app/Config/database.php file as below i.e.
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'db_username',
'password' => 'db_password',
'database' => 'db_name',
//'prefix' => '',
'encoding' => 'utf8',
);
var $mongo = array(
'datasource' => 'mongodb.mongodbSource',
'persistent' => false,
'host' => 'localhost',
'login' => 'db_username',
'password' => 'db_password',
'database' => 'db_name',
//'prefix' => '',
'encoding' => 'utf8',
);
public function __construct() {
if (DEVELOPMENT_MODE) {
$this->default = $this->mongo;
} else {
$this->default = $this->default;
}
}
}
All the above logic are use for Config settings to use through out application.
Now below code is connect Model to mongoDB.
class Test extends AppModel {
var $name = 'test';
var $primaryKey = 'id';
var $useDbConfig = 'mongo'; // setup the mongodb datasource
// Now is model is connected with mongoDB only....
}

defaultAdapter in Zend Framework

when i try to construct a query to my db in my model like
class Application_Model_DbTable_Resume extends Zend_Db_Table_Abstract
{
protected $_name = 'users';
public function getFiveLastResume (){
$select= $db->select()->from('users')->order("id DESC")->limit(5);
$stmt = $db->query($select);
$row = $stmt->fetchAll();
return $row;
}
}
so i have an error Notice: Undefined variable: db
if I write adapter before query
$db = Zend_Db::factory('PDO_MYSQL',array(
'host' => '127.0.0.1',
'username' => 'root',
'password' => '',
'dbname' => 'sport'
));
thats work good. why does my adapter not work ?
my application.ini contain right database config,cuz more simply queries work out good without including adapter. im noob in zend, thanks
$db is undefined in the local scope which is why you get the error.
Since you are inside a DbTable object, you can use $this to get the DB adapter:
public function getFiveLastResume () {
$select = $this->select()->from('users')->order("id DESC")->limit(5);
$stmt = $select->query();
$row = $stmt->fetchAll();
return $row;
}
Anywhere else in your application, you should be able to get a reference to the default DB adapter using:
$db = Zend_Db_Table::getDefaultAdapter();
$select = $db->select()->from('table')...;
This of course assumes you have created a Zend_Db_Table object and set it as the default adapter.

How to define the use of utf-8 in Doctrine 2 in Zend Framework application.ini, when using Bisna

The following ZendCasts cast, shows a way to use doctrine 2 in a zend framework environment.
Using this configuration, how can I make the connection use a utf-8 charset so the magic of "SET NAMES 'utf8'" will happen ?
What I'm really searching for is a way to configure it using the application.ini file.
If that's not possible using this configuration, how can this be done by code ? an _initDoctrine method in the Bootstratp file ?
Thank you.
UPDATE
It appears there's a post connect event which handles this, but I don't see how can I set it up via application.ini (if possible at all).
If not, can I set it up via a bootstrap method ? Will the bootstrap method run before any other doctrine connection code run, when relying on the Bisna library ?
If you are not using Bisna, you could simply do something like the following:
Pass the config stuff directly to EntityManager's connection options
(although driverOptions is not documented)
// $options is a simple array to hold your data
$connectionOptions = array(
'driver' => $options['conn']['driv'],
'user' => $options['conn']['user'],
'password' => $options['conn']['pass'],
'dbname' => $options['conn']['dbname'],
'host' => $options['conn']['host'],
'charset' => 'utf8',
'driverOptions' => array(
1002 => 'SET NAMES utf8'
)
);
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
I'm using the following custom bootstrap resource to initialize doctrine therefore $options is in application.ini and is accessible there by $this->getOptions();
// \library\My\Application\Resource\Doctrine.php
class My_Application_Resource_Doctrine extends Zend_Application_Resource_ResourceAbstract
{
public function init()
{
$options = $this->getOptions();
$config = new \Doctrine\ORM\Configuration();
//doctrine autoloader, config and other initializations
...
$connectionOptions = array(
.... //see above
);
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
$registry = Zend_Registry::getInstance();
$registry->em = $em;
return $em;
}
}
It will bootstrap automatically if you put in application.ini
resources.doctrine.conn.host = '127.0.0.1'
resources.doctrine.conn.user = '...'
resources.doctrine.conn.pass = '...'
....
works fine for me
resources.doctrine.dbal.connections.default.parameters.driverOptions.1002 = "SET NAMES 'UTF8'"
1002 is the integer value of PDO::MYSQL_ATTR_INIT_COMMAND:
Command to execute when connecting to the MySQL server. Will
automatically be re-executed when reconnecting.
Note, this constant can only be used in the driver_options array when constructing a new
database handle.
this worked for me. config/autoload/doctrine.local.php
<?php
return array(
'doctrine' => array(
'connection' => array(
'orm_default' => array(
'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
'params' => array(
'host' => 'localhost',
'port' => '3306',
'user' => '...',
'password' => '...',
'dbname' => '...',
'driverOptions' => array(
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
)
),
)
)
)
);
It is possible to add it via application.ini, provided you use ZendX_Doctrine2 (at https://github.com/mridgway/ZendX_Doctrine2) with MySQL.
Then here's the line you need in application.ini:
resources.entitymanagerfactory.connectionOptions.driverOptions.1002 = "SET NAMES utf8"
(1002 == PDO::MYSQL_ATTR_INIT_COMMAND)
Don't forget to correctly set
default-character-set=utf8
in your my.cnf
Since this is for Doctrine 2, and ZendCasts is using Bisna, I believe you can just add this to your configuration.ini file
resources.doctrine.dbal.connections.default.parameters.driverOptions.charset = "utf8"
I'm not exactly sure how to test if it is sticking or not but let us know.
You could set the default table charset like that to utf8:
// Create new Doctrine Manager instance
$doctrineManager = Doctrine_Manager::getInstance();
// Set charset to UTF8
$doctrineManager->setAttribute(
Doctrine_Core::ATTR_DEFAULT_TABLE_CHARSET,
'utf8'
);
Quote:
an _initDoctrine method in the Bootstratp file ?
Yes.
For LoSo library and Doctrine 2 and MySQL add
resources.doctrine2.connection.driverOptions.1002 = "SET NAMES 'UTF8'"
to your application.ini
I have this in my bootstrap:
protected function _initDoctrineLibrary()
{
require_once('Doctrine/Doctrine.php');
$this->getApplication()->getAutoloader()->pushAutoloader(array('Doctrine', 'autoload'),'Doctrine');
$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(
Doctrine::ATTR_MODEL_LOADING,
Doctrine::MODEL_LOADING_CONSERVATIVE
);
$config = $this->getOption('doctrine');
$conn = Doctrine_Manager::connection($config['dsn'],'doctrine');
$conn->setAttribute(Doctrine::ATTR_USE_NATIVE_ENUM, true);
return $conn;
}
where in the application.ini you see
doctrine.dsn = "mysql://user:password#host/databasename"
I think you can do something similar