write custom query with zend framework 2 - mysql

I want to perform a custom query in zf2. Now I have a Album controller and AlbumTable. Inside AlbumTable, I want to perform an join operation. But I am unable to do this.Please give me some suggation.
below my code:
namespace WebApp\Table;
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Sql;
new Zend\Db\Adapter\Adapter;
class UserTable
{
protected $tableGateway;
public function __construct(TableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function searchUser($search)
{
$search = "mehedi";
$adapter = new Adapter();
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('foo');
$select->join('profiles', 'user.user_id = profiles.ownerId', array('name'));
$select->where(array('id' => 2));
$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute();
return $results;
}
}

The issue is you are trying to instantiate your Adapter with no parameters, when it requires at least a driver :
$adapter = new Adapter(); // Bad
$adapter = new Adapter($driver); // ..
You should use the ServiceManager to get your Adapter, did you start with the Skeleton Application?
It should have already been injected into the TableGateway for you..
$adapter = $this->getAdapter();
An example of instantiating an Adapter:
$config = $serviceLocator->get('Config');
$adapter = new Adapter($config['db']);
where you specify your setup inside your config, local.php will do:
return array(
/**
* Database Config
*/
'db' => array(
'driver' => 'pdo',
'dsn' => 'mysql:dbname=dbname;host=localhost',
'username' => 'root',
'password' => 'password',
),

I got some solution of this problem with helping all of here.
$adapter = $this->tableGateway->getAdapter();
/* $adapter variable is used to fetch Adapter
configuration from serivce manager. */
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('foo');
$select->join('profile', 'foo.skillId = profile.id', array('name'));
$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute();
/* if you want you can see your
desired output in here. */
foreach ($results as $person) {
echo "<pre>";
print_r($person);
}
return $results;

It's because the join method expects an array for the join table. Also I personally would prefix the tables in the query, something like this:-
$search = "mehedi";
$adapter = new Adapter();
$sql = new Sql($adapter);
$select = $sql->select();
// PREFIXED THE foo table f
$select->from(array('f' =>'foo'));
// PREFIXED THE profiles table p
$select->join(array('p' => 'profiles'), 'user.user_id = profiles.ownerId', array('name'));
$select->where(array('id' => 2));
$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute();
return $results;

Related

Yii2-user Dektrium - how to hash password

i want to do hash password and check that with database ( password_hash )
How can I do it????
$username = $auth['username'];
my password is
$password = $auth['password'];
i want hash that :
$find = \dektrium\user\models\User::findOne(['username' => $username, 'password_hash' => $password]);
You could generate the $hash using
$hash = Yii::$app->getSecurity()->generatePasswordHash($password);
$find = \dektrium\user\models\User::findOne(['username' => $username,
'password_hash' => $hash]);
Th code belowe is from dektrium/yii2-user/helpers/password.php ( the code for hash function ..of dektrium adn as you see the extensions use the generatePasswordHash and a cost
public static function hash($password)
{
return \Yii::$app->security->generatePasswordHash($password,
\Yii::$app->getModule('user')->cost);
}
default cost = 8
I know quite late to answer this, but for those who are still looking.. I recently encountered this issue and after lots of testing below code worked for me:
$behaviors['authenticator'] = [
'class' => HttpBasicAuth::className(),
'auth' => function ($username, $password) {
$user = \dektrium\user\models\User::findOne(['username' => $username]);
if ($user->validate($password)) {
return $user;
}
return null;
}
];

Yii 2 - How to set connection in DB Query for multi database

How to set db connection in yii-db-query?
I have a 3 database connection:
db, db2 and db3
When I used this default Query:
$query = (new \yii\db\Query())
->select('*')
->from('trans_journal')
->all();
It will return an error. The trans_journal is not found, because the trans_journal is from the db2 connection.
And when I used this Query:
$query = (new \yii\db\Query())
->select('*')
->from('trans_journal')
->all(\Yii::$app->db2);
The query will be successfully generated but the problem is it will return an array.
Is there another way to solved this?
if you are using an active record model, in your model you can redefine properly the getDB function for each model:
// Model1
public function getDb() {
return Yii::$app->db1;
}
//Model 2
public function getDb() {
return Yii::$app->db2;
}
If you are using command you can set the db in use just in createCommand call
// To get from db1
Yii::$app->db1->createCommand(
(new \yii\db\Query)->select('col1, col2, ... ')->
from('your_table_db1'))->queryAll();
// To get from db2
Yii::$app->db2->createCommand(
(new \yii\db\Query)->select('col1, col2, ... ')->
from('your_table_db2')->queryAll();
The all() method executes the query and returns all results as an array.
You can iterate over the result for get each model eg:
$results = Yii::$app->db1->createCommand(
(new \yii\db\Query)->select('col1, col2, ... ')->
from('your_table_db1'))->queryAll();
foreach($results as $key => $value ){
echo $value->col1;
// or $value['col1];
}
$query = (new \yii\db\Query())
->select('*')
->from('trans_journal')
->all();
$dataProvider = new ActiveDataProvider([
'db' => Yii::$app->get('db2'),
'query' => $query,
]);
$models = $dataProvider->getModels();

PDO in Classes: Call to a member function prepare() on a non-object

I try to work with classes and PDO but I don't know how to fix the Problem.
With the help of var_dump($pdo) in RunQuery (after $pdo = self::$pdo_conn;) i get the value "null". Can anybody please help me how i can get the pdo object there? Or am I completely wrong with it?
index.php
require_once ('assets/socialbar/defines.php');
require_once ('assets/socialbar/mysql/classes/class.socialbar.php');
$ajaxid = 1;
$getinfo = "";
$getinfo = Socialbar::getInfo($ajaxid);
print_r($getinfo);
class.socialbar.php
require_once(MYSQL_DIR . 'config/pdo_connection.php');
class Socialbar extends Connection {
function __construct(){
parent::__construct();
}
public function GetInfo ($ajaxid) {
$sql = "SELECT * FROM uploads WHERE id = :ajaxid ";
$inputs = array('ajaxid' => $ajaxid);
//$stmt = $this->RunQuery($sql, $inputs);
$stmt = parent::RunQuery($sql, $inputs);
$rowCount = $stmt->rowCount();
if($rowCount > 0){
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} else {
return $rowCount;
}
}
}
pdo_connection.php
abstract class Connection {
protected static $pdo_conn;
private $dsn, $user, $pass;
function __construct (){
require_once MYSQL_DIR . 'pdo_config.php';
$host = $config['db']['host'];
$dbname = $config['db']['dbname'];
$port = $config['db']['port'];
$this->user = $config['db']['user'];
$this->pass = $config['db']['pass'];
$this->dsn = "mysql:host=" . $host . ";port=" . $port . ";dbname=" . $dbname;
$this->Start();
}
protected function Start(){
try {
$this->pdo_conn = new PDO($this->dsn, $this->user, $this->pass);
} catch (PDOException $e){
print_r($e);
exit(0);
}
}
function RunQuery ($sql, $inputs=null){
// $pdo = $this->pdo_conn;
$pdo = self::$pdo_conn;
if(is_null($inputs)) {
$pdo->query($sql);
} else {
try {
$stmt = $pdo->prepare($sql);
if ($stmt) {
$stmt->execute($inputs);
} else {
print_r("Unable to prepare query");
}
} catch (PDOException $e) {
print_r($e);
exit(0);
}
}
return $stmt;
}
}
pdo_config.php
$config['db'] = array(
'host' => 'localhost',
'user' => 'root',
'pass' => '',
'dbname' => 'images',
'port' => '3306',
);
IMHO problem is your understanding or misunderstanding of static variables and functions.
So if you declare:
abstract class Connection {
protected static $pdo_conn;
That means that you can access $pdo_conn even if you had not instatntiate the object of your class and did not pass the __construct so if you have not passed __construct what value holds that property? Correct - NULL ;-)
so when you try to:
function RunQuery ($sql, $inputs=null){
// $pdo = $this->pdo_conn;
$pdo = self::$pdo_conn;
What will you get? Correct $pdo = NULL. And commented line looks as correct one.
There is no reason to declare and call pdo_conn as static property.
It could be private, protected even public but not static.
Try to instantiate the object first:
$socialBarObj = new Socialbar();
$getinfo = $socialBarObj->getInfo($ajaxid);
print_r($getinfo);

How can I set connection for Query builder in yii2?

I want to use QueryBuilder:
$rows = (new \yii\db\Query())
->select('id, name')
->from('user')
->limit(10)
->all();
with non-default connection:
\Yii::$app->get('db_mysql')
How can I do this properly?
Use:
$rows = (new \yii\db\Query())
->select('id, name')
->from('user')
->limit(10)
->all(\Yii::$app->db_mysql);
Of course, you have to set db_mysql component in your config
Doc:
/**
* Executes the query and returns all results as an array.
* #param Connection $db the database connection used to generate the SQL statement.
* If this parameter is not given, the `db` application component will be used.
* #return array the query results. If the query results in nothing, an empty array will be returned.
*/
public function all($db = null)
{
$rows = $this->createCommand($db)->queryAll();
return $this->populate($rows);
}
In your model create method
/**
* #return \yii\db\Connection the database connection used by this AR class.
*/
public static function getDb()
{
return Yii::$app->get('db_mysql');
}
after that
$rows = (new \yii\db\Query())
->select('id, name')
->from('user')
->limit(10)
->all(YourModel::getDb());
or
$rows = (new \yii\db\Query())
->select('id, name')
->from('user')
->limit(10)
->all(static::getDb());
in YourModel context

MySQL & PDO : about efficiency

I have the following code :
<?php
try {
# MySQL with PDO_MYSQL
$DBH = new PDO("mysql:host=*****;dbname=****", "****", "*****");
$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
# statement handle (prevents injection)
$STH = $DBH->prepare("SELECT Adresse FROM Agences");
$STH->execute();
# statement handle (prevents injection)
$STHNAMES = $DBH->prepare("SELECT `numero-agence` FROM Agences");
$STHNAMES->execute();
$storeArray = Array();
$nameArray = Array();
while ($row = $STH->fetch()) {
$storeArray[] = $row['Adresse'];
}
while ($row = $STHNAMES->fetch()) {
$nameArray[] = $row['numero-agence'];
}
echo json_encode(
Array("theAddress" => $storeArray,
"theName" => $nameArray)
);
}
catch(PDOException $e) {
echo 'There was an issue inserting thing into database: '.$e->getMessage();
}
?>
My question is : is there a way to combine the two queries and still have an associative array to send back to the client JSON-encoded ? (I am querying this bit of PHP with an ajax call, and need the resulting data)
Thanks.
Can be done in the same query:
# statement handle (prevents injection)
$STH = $DBH->prepare("SELECT Adresse, `numero-agence` FROM Agences");
$STH->execute();
$storeArray = Array();
$nameArray = Array();
while ($row = $STH->fetch()) {
$storeArray[] = $row['Adresse'];
$nameArray[] = $row['numero-agence'];
}