Searching a set of records in Zend Framework - php

I have written code to search for the First name and last name and display those particular records if available and perform actions like update and delete on those records , I have written the following code to search , please tell me what is the correct approach to build a search controller .I am getting the following error :
Message: Method "select" does not exist and was not trapped in __call()
The code I have written in the controller is :
public function searchAction($params)
{
$query = $this->select()
->from(
array('EMPLOYEES'),
array('FIRST_NAME','LAST_NAME','SALARY','HIREDATE')
);
$query = $this->_makeParams($query,$params);
return $this->fetchAll($query);
}
private function _makeParams($query, $params)
{
$firstname = isset($params['firstname']) ? trim($params['firstname']) : '';
$lastname = isset($params['lastname']) ? trim($params['lastname']) : '';
$salary = isset($params['salary']) ? trim($params['salary']) : '';
$hiredate= isset($params['hiredate']) ? trim($params['hiredate']) : '';
if($firstname!='')
{
$name = '%'.$this->quote($firstname).'%';//quote is my own function
$query->where("EMPLOYEES.FIRST_NAME LIKE '?'",$firstname);
}
if($lastname!='')
{
$query->where("EMPLOYEES.LAST_NAME =?",$lastname);
}
if($salary!='')
{
$query->where("EMPLOYEES.SALARY=?",$salary);
}
if($hiredate!='')
{
$query->where("EMPLOYEES.HIRE_DATE=?",$hiredate);
}
}

your error comes from the fact that your calling select() against the controller object instead of the database object:
public function searchAction($params)
{
//$this in this context is a Zend_Controller_Action object
//you need to query against your database object.
$db = Zend_Db_Table::getDefaultAdapter();
$query = $db->select()
->from(
array('EMPLOYEES'),
array('FIRST_NAME','LAST_NAME','SALARY','HIREDATE')
);
$query = $this->_makeParams($query,$params);
//again make sure to query against the database object
return $db->fetchAll($query);
}
if you don't have a database object created in your bootstrap.php or application.ini you can create one with the Zend_Db:
$db = Zend_Db::factory('Pdo_Mysql', array(
'host' => '127.0.0.1',
'username' => 'webuser',
'password' => 'xxxxxxxx',
'dbname' => 'test'
));

public function searchAction($params)
{
$db = Zend_Registry :: get('db');
$select = $db->select();
$query = $select->from(
array('EMPLOYEES'),
array('FIRST_NAME','LAST_NAME','SALARY','HIREDATE')
);
$query = $this->_makeParams($query,$params);
return $this->fetchAll($query);
}
You are getting the error because you have not created the object of Zend registry.So copy the function and replace your code

Related

Dynamic Database Switch - Codeigniter

I want to switch my codeigniter multiple database on runtime. My Default database will run thoroughly the page but when I needed to switch to other database based on scenario or requirement then I can do. The common model function will work for the all different databases. So, I want to use same model and same function for multiple database connection using dynamic selector without using session or without passing function variable
To achieve this I set a name in cofig and when I call my model I set the required database name in controller before calling model and then I tried to get the name in model which is set in controller. But unfortunately I'm not getting the name from controller to model.
Database Configuration File -
$db['default'] = array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'root',
'password' => 'pass'
'database' => 'db1'
.......
);
$db['anotherDB'] = array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'root',
'password' => 'pass'
'database' => 'db2'
.......
);
Controller -
$this->config->set_item('active_db', 'anotherDB');
$sql = 'select * from user';
$anotherDB_record = $this->model->customQuery($sql);
print_r($anotherDB_record);
$this->config->set_item('active_db', 'default');
$sql = 'select * from customer';
$default_record = $this->model->customQuery($sql);
print_r($default_record);
Mode -
protected $database;
function __construct() {
parent::__construct();
$oDB = $this->config->item('active_db');
$this->database = $this->load->database($oDB, TRUE);
}
function customQuery($sql){
$query = $this->database->query( $sql );
return $query->result();
}
This is the way I have tried to switch my database. If you guys have any other best solution to switch multiple database then please feel free to suggest me.
Try bellow example for dynamically configure another database
common model
function getOtherDB($groupID) {
$getRecord = $this->common_model->getRow('group_master', 'GroupID', $groupID);
if ($getRecord) {
$config['database'] = $getRecord->DBName;
$config['hostname'] = $getRecord->DBHostIP;
$config['username'] = $getRecord->DBHostUName;
$config['password'] = $getRecord->DBHostPassw;
$config['dbdriver'] = "mysqli";
$config['dbprefix'] = "";
$config['pconnect'] = FALSE;
$config['db_debug'] = TRUE;
$DB2 = $this->load->database($config, TRUE);
if ($DB2) {
return $DB2;
}
}
return FALSE;
}
In the above example, I have group_master table which has group wise database details by passing GroupId I fetch the record and set Another database according to group Make sure your all database configuration information stored in the database is encrypted format Use below example to fire query on Other database
$result = $DB2->query("select * from group");
// $DB2 is other database instance you can create multiple db connection using above methos

Doctrine QueryBuilder undefined method getQuery()

When I execute the method getMachineSettings I get an error:
Fatal error: Uncaught Error: Call to undefined method Doctrine\DBAL\Query\QueryBuilder::getQuery()
$data is an associative array:
$data['param'] = 'ip';
$data['value'] = '192.168.240.10';
If I replace getQuery()->getResult() with execute(), $result contains the query:
SELECT * FROM machine WHERE ip = ?
public function __construct()
{
try
{
$dbconf = parse_ini_file('.htLogin.ini');
$config = new \Doctrine\DBAL\Configuration();
$connectionParams = array
(
'dbname' => $dbconf['infoDb'],
'user' => $dbconf['infoLogin'],
'password' => $dbconf['infoPw'],
'host' => $dbconf['infoHost'],
'driver' => 'pdo_mysql',
'charset' => 'utf8',
'driverOptions' => array
(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
)
);
$this->mysql = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
}
catch(PDOException $e)
{
echo $e -> getMessage();
}
public function getMachineSettings($data)
{
$qb = $this->mysql->createQueryBuilder();
$qb->SELECT('*')
->FROM('`machine`')
->WHERE($data['param'] . ' = :value');
$qb->setParameters(
array
(
':value' => $data['value']
)
);
$results = $qb->getQuery()->getResult();
var_dump($result);
return $result;
}
Do you have any idea why the method getQuery() is not recognised?
Just do
$results = $qb->execute()->fetchAll();
Ignore the below - it assumes that your using the Doctrine ORM, which your not
The issue your having is that the QueryBuilder object your working with isn't the Doctrine ORM QueryBuilder - its the DBAL QueryBuilder.
You need to use the createQueryBuilder function from the EntityManager.
/** #var Doctrine\ORM\QueryBuilder $qb */
$qb = $this->entityManager->createQueryBuilder();
Then you can use the select / from etc methods and to get the result of the query you can run
$qb->getQuery()->getResult()
If I was to rewrite your function I would write it like this
public function getMachineSettings(string $field, string $value)
{
$qb = $this->entityManager->createQueryBuilder();
$qb->select('m')
->from('machine')
->where($field.' = :value');
$qb->setParameter('value', $value);
$results = $qb->getQuery()->getResult();
var_dump($result);
return $result;
}
Then you know that the function requires 2 parameters to function, passing an array doesn't let you immediately see what the function requires

Including Classes without having to redefine

So I know that in order for a.class.php to be used within b.class.php I would need to have the a class included in the b class file. My question is this.
I have two classes files at the moment within my website platform. db.class.php and account.class.php
db.class.php
<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/settings.php');
class db extends pdo{
//Website Variables
public $sitedb = '';
public $siteconfig;
public $sitesettings = array(
'host' => SITEHOST,
'database' => SITEDB,
'username' => SITEUSER,
'password' => SITEPASS,
);
public $realmdb = '';
public $realmconfig;
public $realmsettings = array(
'host' => REALMHOST,
'database' => REALMDB,
'username' => REALMUSER,
'password' => REALMPASS,
);
public function __construct(){
$this->sitedb = new PDO(
"mysql:host={$this->sitesettings['host']};" .
"dbname={$this->sitesettings['database']};" .
"charset=utf8",
"{$this->sitesettings['username']}",
"{$this->sitesettings['password']}"
);
$this->realmdb = new PDO(
"mysql:host={$this->realmsettings['host']};" .
"dbname={$this->realmsettings['database']};" .
"charset=utf8",
"{$this->realmsettings['username']}",
"{$this->realmsettings['password']}"
);
$this->sitedb->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$this->realmdb->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
}
}
$db = new db();
account.class.php
<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/settings.php');
class account extends db {
public function Login() {
$query = <<<SQL
SELECT id
FROM profile
WHERE password = :password
SQL;
$resource = $db->sitedb->prepare ( $query );
$resource->execute( array(
':password' => sha1(strtoupper($_POST['email'].':'.$_POST['password'],
));
$row_count = $resource->rowCount();
echo $row_count;
}
}
$account = new account();
This current format tells me that db cannot be redefined, however if I remove the requirement of including the settings file which has
foreach (glob("functions.d/*.class.php") as $class)
{
include $class;
}
It then tells me that class db cannot be found. What way can I work around to have this work correctly?
Turns out the best way to accomplish this was to keep the includes correctly and have all classes within the same file and within my include page utilizing classes have global $db or global $account depending on what I class function I was calling on.

PHP Class - return a row ID in the __construct and always reference that

Trying to get my head around using classes and using it as an object.
Im am converting a number of functions to use one single class. This class is for customers.
What I want to do is create the new customer object:
$customer = new Customer($customer_info);
My class currently looks:
class Customer {
private $customer_info;
private $mysqli;
function __construct(Array $customer_info, Mysqli $mysqli) {
$this->mysqli = $mysqli;
$this->customer_info = $customer_info;
$result = $mysqli->query("SELECT * FROM `customers` WHERE id = 33");
$customerArray = array();
while ($customer = $result->fetch_object()) {
$customerArray[] = array(
'id' => $customer->id,
'first_name' => $customer->first_name,
'last_name' => $customer->last_name,
'email' => $customer->email
);
}
$customer_ID = $customerArray->id;
//return var_dump($customerArray);
}
function getCustomerId() {
return "id:$customer_ID";
}
}
When I create a new customer object, I am passing in the information and then I want to either insert a row or update a current one with the new customer information array thats passed in.
That is fine, I have done that else where in another function.
However, after this I want to be able to use a number of functions on that object.
So example:
$customer = new Customer($customer_info); // create / update
$customer = customer->getCustomerID();
I would like that getCustomerID function to simply return the ID of the database row that was created / updated when the new object was initiated. In my class currently you can see how I tried to set a value and then use that in the function... but im sure thats not how it works.
I have used Laravel and want it to work similar to the way the classes work there.
Thanks.
you have to create Class variables
class Customer {
private $customer_info;
private $mysqli;
public $customer_ID;
function __construct(Array $customer_info, Mysqli $mysqli) {
$this->mysqli = $mysqli;
$this->customer_info = $customer_info;
$result = $mysqli->query("SELECT * FROM `customers` WHERE id = 33");
$customerArray = array();
while ($customer = $result->fetch_object()) {
$customerArray[] = array(
'id' => $customer->id,
'first_name' => $customer->first_name,
'last_name' => $customer->last_name,
'email' => $customer->email
);
}
$this->customer_ID = $customerArray->id;
//return var_dump($customerArray);
}
function getCustomerId() {
return $this->customer_ID;
}
}

zend_db and join

I am trying to understand how to use Zend_DB in my program but I have some problems. The class below (DatabaseService) works when I pass it a simple query. However, if I pass it a query with a join clause my page just hangs and no error is returned. I cut and paste the qry in a query browser and it is valid
Any help would be great
$SQL = "select name from mytable"
$db = new DatabaseService($dbinfo)
$db ->fetchall($SQL ) // works
-----------------------------------------------------------
$SQL = "select count(*) as cnt from EndPoints join CallID on EndPoints.`CallID` = CallID.CallID where EndPoints.LastRegister >= '2010-04-21 00:00:01' and EndPoints.LastRegister <= '2010-04-21 23:59:59' "
$db = new DatabaseService($dbinfo)
$db ->fetchall($SQL ) // DOES NO WORK
class DatabaseService
{
function DatabaseService($dbinfo,$dbname="")
{
try
{
$dbConfig = array(
'host' => $this->host,
'username' => $this->username,
'password' => $password,
'dbname' => $this->dbname );
$this->db = Zend_Db::factory($this->adapter, $dbConfig);
Zend_Db_Table::setDefaultAdapter($this->db);
}
catch(Zend_Exception $e)
{
$this->error = $e->getMessage();
Helper::log($this->error);
return false;
}
}
public function connnect()
{
if($this->db !=null)
{
try
{
$this->db->getConnection();
return true;
}
catch (Zend_Exception $e)
{
$err = "FAILED ::".$e->getMessage()." <br />";
}
}
return false;
}
public function fetchall($sql)
{
$res= $this->db->fetchAll($sql);
return $res;
}
}
I can't see why that wouldn't work. It could be a bug in a particular release of ZF but as far as I can tell there are no SQL syntax errors. What you could do is Bootstrap the Zend_Db class somewhere in your system like in the index.php file just as you were doing in your DatabaseService class:
$dbConfig = array(
'host' => 'hostname',
'username' => 'username',
'password' => 'password',
'dbname' => 'dbname'
);
$db = Zend_Db::factory('mysqli', $dbConfig);
$db->setFetchMode(Zend_Db::FETCH_OBJ);
Zend_Db_Table::setDefaultAdapter($db);
And then Zend Framework should handle the connection process for you. Then instead of having a DatabaseService class you just create a model for each table you need like so:
<?php
class EndPoints extends Zend_Db_Table_Abstract
{
protected $_name = 'EndPoints';
/**
* the default is 'id'. So if your table's primary key field name is 'id' you
* will not be required to set this. If your primary key is something like
* 'EndPointsID' you MUST set this.
* #var primary key field name
*/
protected $_primary = 'EndPointsID';
}
Doing this will automagically give you access to functions such as fetchRow(), fetchAll(), find(), etc. Then you can also use Zend_Db_Table_Select for your queries which can be quite useful. Like so:
<?php
$endPointsModel = new EndPoints();
$callIdCount = $endPointsModel->getCallIdCount('2010-04-21 00:00:01', '2010-04-21 00:00:01');
Then in your EndPoints model you would create that function like so:
...
public function getCallIdCount($fromDate, $toDate)
{
$cols = array('cnt' => 'count(*)');
$select = $this->select->setIntegrityCheck(false) // this is crucial
->from($this->_name, $cols)
->join('CallID', "{$this->_name}.CallID = CallID.CallID", array())
->where("{$this->_name}.LastRegister >= ?", $fromDate)
->where("{$this->_name}.LastRegister <= ?", $toDate);
// if you need to see what the whole query will look like you can do this:
// echo $select->__toString();
return $this->fetchAll($select);
{

Categories