Executing simple query issue in Zend 2 - zend-framework2

I want to execute two queries in zend 2 :
This is the content of my model file:
$email = $getData['login_email'];
$password = $getData['login_password'];
$select = $this->adapter->query ("select count(*) as counter from users where email = '$email' and password = '".md5($password)."'");
$results = $select->execute();
if ($results->current()['counter'] == 1 ){
// $update_user = $this->adapter->query("UPDATE users SET session_id = '".$session_id."' WHERE email = '".$email."'");
try {
$update_user = $this->adapter->query("select * from users");
} catch (\Exception $e) {
\Zend\Debug\Debug::dump($e->__toString()); exit;
}
$update_session = $update_user->execute();
For some reason if i remove one random query, the another one will be executed. I know it is weird but i believe there is a rational answer to it. The result of the try catch part is:
I did not write it wrong the query. AS you can see I tried a simple select query and i got the same result. Actually I have no idea what is wrong this. Please help with this, I'm looking up for an answer on the internet during the last 5-6 days and I found nothing. If you want me to provide any more information, please ask. THX

As this answer suggests, this is an issue with the mysqli driver using unbuffered queries by default.
To fix this, you have to buffer the result of the first query before running the next one. With ZF2, the Result interface has a buffer() method to achieve this :
$results = $select->execute();
$results->buffer();

Related

insert blob not working (mysql_real_escape_string)

I am trying to copy image blobs from one table to another, and it is not working, since the mysql_real_escape_string () is no longer available. The special characters in the blob are blocking the insert and I can't figure out how to correct this. Your help would be appreciated. Thank you.
foreach ($dbh->query($query_images) as $images-1) {
$ins = "INSERT INTO images-2 SET image_blob='".images-1['image_blob']."'";
$dbh->exec($ins);
}
First you have:
$ins = "INSERT INTO images-2 SET image_blob='".images-1['image_blob']."'";
when you likely want:
$ins = "INSERT INTO images-2 SET image_blob='".$images-1['image_blob']."'";
but that could just be a typo in your post.
You can do this in pure MySQL and not have to iterate through each row in the images-1 table:
INSERT INTO images-2 (image_blob) VALUES (SELECT image_blob FROM images-1)
If it is some kinda of escaping problem I would suggest going with the PDO stuff in PHP:
$pdo = new PDO('mysql:host=hostname;dbname=db', $user, $pass);
foreach($dbh->query($query_images) as $images-1) {
$sth = $pdo->prepare("INSERT INTO images-2 SET image_blob=?")
$sth->execute([$images-1['image_blob']]);
}
I did not test any of this code but just put it together based on documentation and experience.

Zend 2 - is tableGateway producing safe queries from sql injection?

I was trying to search for information, but so far cannot see. Also checked in the documentation but did not see.
https://framework.zend.com/manual/2.2/en/modules/zend.db.table-gateway.html
So are my queries safe? For example
$rowset = $this->tableGateway->select(['email' => $email]);
Yes it does.
You can try the following code to check if the generated SQL statement is safe.
$sql = $this->tableGateway->getSql();
$select = $sql->select()->where(array("email" => $someDirtyInputHere));
// you can execute the query using $this->tableGateway->selectWith($select);
// output query
echo $sql->getSqlStringForSqlObject($select);
exit;

Zend framework 2 CSV data as an array or string

I am still very new to Zend and running into some issues on exporting my data to a CSV.
I found a great resource that explains the headers and download part here however I am running into issues when trying to export the actual data.
If I create a variable like $content = "test" the export works fine using the code above.
However when I duplicate my indexAction code, make some changes, and bring it into my downloadAction, I am getting issues that I believe are due to my content being returned as an Object rather than an array or string.
My Module is grabbing the SQL by using:
public function fetchAllMembers($order = null , $order_by = null, $selectwhere = null) {
$session = new SessionContainer('logggedin_user');
$sql = new Sql($this->adapter);
$select = new Select();
$select->from(array('u' => 'tbl_all_data'));
if ($selectwhere != null){
$select->where($selectwhere);
}
$select->order($order_by . ' ' . $order);
$selectString = $sql->getSqlStringForSqlObject($select);
$results = $this->adapter->query($selectString, Adapter::QUERY_MODE_EXECUTE);
$results->buffer();
return $results;
}
and my Controller is calling that SQL by using:
$content = $modulesTable->fetchAllMembers($order, $order_by, $where);
Any help would be greatly appreciated, and I don't need anyone to write the code for me just help with pointoing me in the right direction.
$this->adapter->query returns a Zend\Db\ResultSet object. So you need to call $results = $results->toArray(); to send an array.
Also you need to loop through the array and echo it out in your view file.
Results, returned by adapter are ResultSet type. I guess you need to call at least
current()
method to grab some data. And they will be of array type, so, again you need to do something with them.
toArray() is often used to quickly get data.
More sophisticated way to get data, is to use next() method with current():
$firstThing = $result->current();
$result->next();
$result->next();
$thirdThing = $result->current();
It's just an example, but it can be useful in some cases.

How to make LIMIT work in Grails HQL executeUpdate()?

I'm running grails 1.3.6 and I have this code:
String hql = '''
UPDATE
ApiResponse a
SET
a.lockId = :lockId
WHERE
a.lockId = 0
ORDER BY
a.dateAdded asc
LIMIT 5
'''
ApiResponse.executeUpdate(hql, [lockId : workerId])
It seems that this code updates all rows in DB instead of the 5 oldest entries. Does this mean LIMIT is not working in HQL? Please help me how to achieve the same SQL logic in GORM or HQL. Basically, I need to do a bulk update using LIMIT.
what i do (grails 1.3.7):
ExAus.executeQuery( "select distinct <field> from <controller>", [max: 20, offset: 0] )
While waiting for someone to reply, I think I found a workaround. Here it is:
def c = ApiResponse.createCriteria()
def targetList = c.list {
eq('lockId', 0)
maxResults(5)
order("dateAdded", 'asc')
}
String hql = '''
UPDATE
ApiResponse
SET
lockId = :lockId
WHERE
id in (:ids)
'''
ApiResponse.executeUpdate(hql, [lockId : workerId, ids: targetList.collect {it.id}])
I believe this approach can still be considered same logic with the original. However, this has to make 2 queries.
Feel free to suggest other approaches. Thanks!
I know the post is quite old but the question is still relevant since I had the same problem.
I fell back to using Groovy sql (jdbc) instead.
You will need to inject the dataSource object within your service/controller first by using:
def dataSource
Then you may do this in your method:
String sqlQuery = '''
UPDATE
API_RESPONSE a
SET
a.LOCK_ID = :lockId
WHERE
a.LOCK_ID = 0
ORDER BY
a.DATE_ADDED asc
LIMIT 5
'''
def sql = new Sql(dataSource)
sql.executeUpdate(sqlQuery, [lockId : workerId])
Note that you will need to use the database native table and column names in the sql query.

setBaseQuery not working on Tasks in Symfony

I'm building a Task in Symfony with Doctrine. I'm getting all the places to make a batch update to a particular field. This has to be done in two languages. I'm using setBaseQuery() to make the JOIN on the query with the language I want.
If I do the following in an action, it works without any problem. However, If I do it in a task; it doesn't work as expected. The task runs perfectly two times (one in english and the other in english too!).
Any ideas on what I have to do different on tasks?
thanks!
$languages = array('es' => 'Spanish', 'en' => 'English');
foreach($languages as $lang => $value) {
// get all the places
$q = Doctrine::getTable('Place')
->createQuery('p')
->leftJoin('p.Translation ptr')
->addWhere('ptr.lang = ?', $lang);
$treeObject = Doctrine::getTable('Place')->getTree();
$rootColumnName = $treeObject->getAttribute ( 'rootColumnName' );
$treeObject->setBaseQuery($q);
// all the continents
foreach ( $treeObject->fetchRoots() as $continent ) {
$this->log(date("Y-m-d H:i:s").' '.$lang.' Continent '.$continent->title);
..
}
}
To gain database access in your tasks you'll need to call the following in your execute() method before any other database calls:
$databaseManager = new sfDatabaseManager($this->configuration);
http://www.symfony-project.org/book/1_2/16-Application-Management-Tools#chapter_16_sub_custom_tasks_new_in_symfony_1_1
so the solution I've found is adding $model->Translation[$lang]->title. It's strange because the title should have been loaded through the setbasequery; but it seems not.
// all the continents
foreach ( $treeObject->fetchRoots() as $continent ) {
$this->log(date("Y-m-d H:i:s").' '.$lang.' Continent '.$continent->Translation[$lang]->title);
..
}
Update
I'm getting the translation but $continent->save() didn't save the changes in Spanish (however it's saving it in English). I had to do a manual query in Doctrine:
$con = Doctrine_Manager::getInstance()->connection();
...
$con->execute("update model_translation set field='".$field."' where id='".$model->id."' and lang='".$lang."'");
now everything works...

Resources