update query with functions in typo3 - php

I'm trying to use the typo3 update function with the mysql CONCAT function. Can you tell me how to manage that? What I tried:
$updateArray = array("field" => 'CONCAT( field'.','.$toAppend.')');
$GLOBALS['TYPO3_DB']->exec_UPDATEquery ('table','id = '.'"'.$some_id.'"',$updateArray);
That does not work, because that query is executed:
UPDATE table
SET
pagesEdited='CONCAT( field,'value')'
WHERE
id = "id"
As you see, the concat function is escaped.

The reference documentation isn't very clear about it, however, just appending TRUE to your parameters of the update function should disable quoting:
$GLOBALS['TYPO3_DB']->exec_UPDATEquery ('table','id = '.'"'.$some_id.'"',$updateArray, TRUE);
That also means that you will have to do your own input sanitization before lauching the query, if you haven't already:
$toAppend = $GLOBALS['TYPO3_DB']->fullQuoteString($toAppend, "");

Have a look at the noQuote parameter of the fullQuoteArray() method of TYPO3\CMS\Core\Database\DatabaseConnection that is used by exec_UPDATEquery():
#param boolean|array $noQuote List/array of keys NOT to quote (eg. SQL functions) - ONLY for associative arrays
And when you take a kloser look ath this method, you will see that a simple true does not do the trick as expected. Simply use a list of fields (comma separated list) or an array to let TYPO3 know which fields should not be escaped.
In your case it would look like this:
$updateArray = array(
'field' => 'CONCAT(field,' . $GLOBALS['TYPO3_DB']->fullQuoteString($toAppend, 'table') . ')',
);
$where = 'id = ' . $GLOBALS['TYPO3_DB']->fullQuoteString($some_id, 'table');
$GLOBALS['TYPO3_DB']->exec_UPDATEquery ('table', $where, $updateArray, 'field');

Related

PHP CodeIgniter Framework - Does Query Builder count as a prepare() and bind_param() and how to store form post data into Query Builder array?

I'm not finding much documentation-wise beyond some sources saying Query Builder statements are prepared, and others saying they are but not bound, then some saying they are bound etc. A solid answer would be much appreciated.
Furthermore, if I wanted to have my form data passed through into an array that I'm storing in my database, how should my following code be modified?
$user_first = $this->input->post('user_first');
$data['user_first'] = $user_first;
//this above code works fine if I want to store each part of the form
//in the array individually
$data = array(
'user_first' => 'My title'
//How can I get 'user_first' to => $user_first?
);
$this->pdo->insert('users', $data);
Thank you.
A few ways
//adding name by name to an array
$data = array('user_first' => $this->input->post('user_first'));
adding the entire post array
//as u have the same "name" in the form than the array u are sending to the db insert method
$data = $this->input->post();
//in short $this->input->post() is $_POST array, but cleaned
//or getting the values from $_POST
$data = array('user_first' => $_POST['user_first']);
Hope my answer helps u.
The answer depends to a large extent on what "prepared" means. "Binding" can be accomplished in a way very much like PDO. However, there are no methods that correspond to PDOStatement::bindColumn, PDOStatement::bindParam, or PDOStatement::bindValue.
The most direct equivalent to PDO::prepare() with "binding" would be as follows
$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?";
$this->db->query($sql, array(3, 'live', 'Rick'));
The ? placeholders are replaced with the values in the array in the order they appear in the array. The input values will be escaped. The query() method does not support the PDO sytax of :name as a placeholder. (CI documentation on Query Binding.)
In general the various Query Builder methods combine to achieve the same overall effect as PDO::prepare() and PDOStatement::execute().
The functionality of PDOStatement methods to retrieve queried data (e.g. execute(), fetch(), etc.) are accomplished by calls to CI database methods for "Generating Query Results".
Assuming the three input from my example above have been posted by a here's how I would accomplish inserting them in a table
$data['id'] = $this->input->post('id');
$data['status'] = $this->input->post('status');
$data['author'] = $this->input->post('author');
$this->db-insert('some_table', $data);
If the element names are an exact match for the table column names and we know only those inputs will be posted the above could be simplified to
$this->db-insert('some_table', $this->input->post());

Sanitise query in SQL and PHP using in_array()

Using MySQL and PHP, a typical (PDO) query looks like this:
// prepare the query
$q = $DB->prepare("SELECT * FROM table_name WHERE property = :value");
// run the query
$q->execute(array(':value'=>$value));
This is safe from SQL injection, as the property value is treated separately to the query.
However if I want to use the same code to write a query that might retrieve a different field or different grouping, you cannot use the prepare/execute method alone, as you cannot use PDO parameters for fields (see here).
Can you simply use in_array() to check a field name, like this:
// return false if the field is not recognised
if(! in_array($field_name, array('field1','field2','field3')) return false
// run the query
$q = $DB->query("SELECT * FROM table_name ORDER BY " . $field_name);
Is there a safer / quicker way?
Already seems quite fast and secure. Maybe add backticks around the field name in the query.
To speed it up slightly you can use an assoc array and just check if the index exists instead of searching the contents of an array.
$fields = array('field1' => null, 'field2' => null, 'field3' => null);
if (!array_key_exists($field_name, $fields)) return false;
furthermore isset is faster than array_key_exists
if (!isset($fields[$field_name])) return false;
function benchmarks

Zend 2 - DB - Escape value without quoting it

I'm looking for a clean way to escape value for SQL query without quoting it.
Let's say i have a value It's cool. Now I would like to simply get escaped string It\'s cool, just like when using for example mysqli_real_escape_string() function for mysqli driver.
The problem is that all Zend\Db\Adapter\Platform interface's quoting methods adds single quotes to the value which means I get 'It\s cool'.
Simplest way I found to do this is to trim quotes after usage of quoteValue() method.
$raw = "It's cool";
$quoted = $this->db->platform->quoteValue($raw);
$final = trim($quoted, "'");
But it's of course a dirty solution and I don't want it to be like this in every place I need escaped-only value.
Is there any clean way to do this simple thing in Zend2?
Maybe you can try something like this:
$sql = "UPDATE posts set comment = :value where id = :id";
$data = ['value' => "It's cool", 'id' => 123];
$stmt= $this->tableGateway->getAdapter()->createStatement($sql);
$stmt->prepare($sql);
$stmt->execute($data);

Using WHERE CONCAT with Active Record in CodeIgniter

The raw query I'm trying to get plugged in here is:
SELECT * FROM x WHERE CONCAT(y, ' ', x) LIKE '%value%';
I've checked through the AR docs and can't find anything that would allow me to do this. I'm not very familiar with how exactly it's constructing these queries, and was hoping someone could point me in the right direction. Thanks a bunch.
If you want to use the AR class you need to pass FALSE as third parameter to avoid the query being escaped automatically. You are now left to escaping the argument by yourself:
$value = $this->db->escape_like_str($unescaped);
$this->db->from('x');
$this->db->where("CONCAT(y, ' ', x) LIKE '%".$value."%'", NULL, FALSE);
$result = $this->db->get();
Refer to point 4) in the Active Record session of the manual. Quoting:
Custom string:
You can write your own clauses manually:
$where = "name='Joe' AND status='boss' OR status='active'";
$this->db->where($where);
$this->db->where() accepts an optional third parameter. If you set it to FALSE, CodeIgniter will not try to protect your field or table names with backticks.
$this->db->where('MATCH (field) AGAINST ("value")', NULL, FALSE);
An easier way, imho, whould be to run a "regular" query and take advantage of binding:
$result = $this->db->query("CONCAT(y, ' ', x) LIKE '%?%'", array($value));
Or use an associative array method without using the third parameter:
$a = array(
'CONCAT(`y`, " ", `x`)' => $value,
'title' => $title,
...
);
...
$this->db->like($a);
Will be generated WHERE part of the query:
... WHERE CONCAT(`y`, " ", `x`) LIKE '%test value%' AND `title` LIKE '%test title%' AND ...
Obviously useful when using more than one search parameters.
something like this should work:
$this->db->where("CONCAT(y, ' ', x) LIKE '%value%'");
$this->db->get(x);
This is old but...
You can try this:
$this->db->like('CONCAT(field_name," ",field_name_b)',$this->db->escape_like_str('value'));

get_where with md5()

I want to perform this simple query using Codeigniter:
$user = $this->db->get_where($type,array("id"=>$id));
$type is the name of the table and
$id is a md5() value so I want to do something like $this->db->get_where($type,array(md5("id")=>$id)); that of course is not possible to do.
the answer could be $this->db->query('select * from $type where MD5(id) = $id'); but I would prefer a more compact way like get_where() to perform query.
any suggestions?
$this->db->where('MD5(id)', $id, FALSE);
The 3rd argument when set to FALSE will stop CI from protecting your field and table names with backticks so instead of turning the code into:
WHERE `MD5(id)` = 'THE ID'
it will be:
WHERE MD5(id) = 'THE ID'
$this->db->get_where($type,array("md5(id)"=>$id)); works perfectly. I get the record I want.
To answer the original question which I came across recently and found this as the top result in Google.
$user = $this->db->get_where( $type, array( 'md5( id ) =' => $id ) );
You can also substitute = for other operators such as LIKE and NOT LIKE.

Categories