PHP get Array(s) when is directly defined in $string - php

When is Array defined in string (like in sample below), is possible get the information of this Arrays?
$id = 1;
$query =
"
SELECT *
FROM category
WHERE
id > " . [$id, 'int'] . " AND
title LIKE " . ['%test%', 'str'] . "
ORDER BY id ASC
";
$select = sql ($query);
var_dump($query) // output
//SELECT * FROM category WHERE id > Array AND title LIKE Array ORDER BY id ASC
/*
var_dump ($query->my_defined_arrays_are)
[0] => 1
[1] => '%test%'
*/
i need this for better orientation in most complex queries for $sql->bind_param();
SOLUTION:
I created small function bind() which create and store the bind data and then send it to the sql() function where are processed. This works on all queries types (SELECT, INSERT, UPDATE, DELETE..etc.).
Important for me is clear and easy readable code.
Query:
$query =
"
SELECT *
FROM category
WHERE
id > " . bind('1', 'int') . " AND
title LIKE " . bind('%test%', 'str') . "
ORDER BY id ASC
";
$select = sql ($query, $bind);
/*
var_dump ($query)
SELECT * FROM category WHERE id > {Bind_Array} AND title LIKE {Bind_Array} ORDER BY id ASC
*/
Functions:
function bind($param, $type) {
global $bind;
$bind[] = $param . ', ' . $type;
return '{Bind_Array}';
}
function sql($query, $bind_param = []) {
global $settings, $bind;
$bind = null; // clean variable; must be empty for all next operations
$mysqli = new mysqli (
$settings['db_hostname'],
$settings['db_username'],
$settings['db_password'],
$settings['db_database']
);
if ($mysqli->connect_errno) {
echo 'Failed to connect to MySQL: (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error;
return;
}
if (!$mysqli->set_charset('utf8')) {
echo 'Error loading character set utf8: (' . $mysqli->character_set_name() . ') ' . $mysqli->error;
return;
}
if ($bind_param != null) {
unset ($tmp_bind, $tmp_type);
// reserve first key
$tmp_bind[0] = null;
// replace all occurences string in query
$query = preg_replace ('/({Bind_Array})/', ' ?', $query);
// create parameters from array
foreach ($bind_param as $params) {
// explode and clean parametres
$param = array_map ('trim', explode (',', $params));
if (count ($param) != 2) {
echo 'Too much or less parameters!';
return;
}
// first is content
$tmp_bind[] = $param[0];
// second is type; create right format
$tmp_type .= str_replace (array ('int', 'str', 'double'), array ('i', 's', 'd'), $param[1]);
}
// set types to the first reserved key
$tmp_bind[0] = $tmp_type;
// replace previdous incoming data with new created
$bind_param = $tmp_bind;
}
if (!($sql = $mysqli->prepare($query))) {
echo 'Prepare failed: (' . $mysqli->errno . ') ' . $mysqli->error;
$mysqli->close();
return;
}
if (!empty ($bind_param) && $type = array_shift ($bind_param)) {
// $sql->bind_param()
call_user_func_array (array ($sql, 'bind_param'), array_merge (array ($type), array_map (function (&$item) { return $item; }, $bind_param)));
}
if (!$sql->execute()) {
echo 'Execute failed: (' . $sql->errno . ') ' . $sql->error;
$sql->close();
return;
}
if (strpos ($query, 'SELECT ') !== false || strpos ($query, 'SHOW ') !== false) {
// proceed this only if is SELECT or SHOW query
if (!($res = $sql->get_result())) {
echo 'Getting result set failed: (' . $sql->errno . ') ' . $sql->error;
$res->close();
return;
}
// store data to $output for use
for ($row_no = ($res->num_rows - 1); $row_no >= 0; $row_no --) {
$res->data_seek($row_no);
$output[$row_no] = $res->fetch_assoc();
}
$res->close();
}
$sql->close();
unset ($tmp_bind);
return $output;
}

The answer to your question is "No". When you add an array to a string, you get a string, and the original array is lost in the string "Array".
So -- why are you doing this?
My guess is that you're trying to come up with a compact representation of a query - a single object containing information on the query and its parameters (if any). This can be done, but requires some code to go with it.
For example you can create a class of your own holding the query in PDO format, with placeholders:
SELECT * FROM category WHERE id > :param1 ...
and also an array of parameters with their types:
[ 'param1' => 'int', ... ]
Then you might need a __toString() method to yield a string representation that is of use for you. The above representation can immediately be used by PDO.
Now, to specify a query with its parameters, you can use a compact representation not too unlike the one you used, leveraging an array of arrays (note that there is no string concatenation here, but rather array concatenation):
$query = ["SELECT * FROM tbl WHERE id >",['int']," AND ..." ...];
To convert from this "shorthand" to the more useable PDO_String / PDO_Param_Array representation, you could walk $query concatenating all non-string elements with placeholder parameters:
$queryString = '';
$queryParams = [ ];
$n = 1;
foreach ($query as $item) {
if (is_string($item)) {
$queryString .= $item;
} else {
$queryString .= ':param' . $n;
$queryParams[":param{$n}"] = $item[0];
$n++;
}
}

Related

How can i return an array in php function

I need a return array in function. When i was use that returning this Array ( ):
function menuOlustur($ana_kategoriler){
global $db;
$alt_kategori_durum = '';
$alt_kategori;
foreach ($ana_kategoriler as $kategori) {
$alt_kategori = $db->rawQuery('select * from s_kategoriler where kategori = ' . $kategori['id'] . ' and durum=1 order by sira asc');
}
return $alt_kategori;
}
and i was use this returning one more index in array.
function menuOlustur($ana_kategoriler){
global $db;
$alt_kategori_durum = '';
$alt_kategori;
foreach ($ana_kategoriler as $kategori) {
$alt_kategori[] = $db->rawQuery('select * from s_kategoriler where kategori = ' . $kategori['id'] . ' and durum=1 order by sira asc');
}
return $alt_kategori;
}
My $ana_kategoriler is an array its a calling query like that
$ana_k_cek = $db->rawQuery('select id, kategori, adi_' . $dil . ' as adi,link_' . $dil . ' as link from s_kategoriler where m_id=5 and durum=1 order by sira asc ');
whats can i do ?
EDIT: fixed query, should not be kategori = 1,2,3,4, but kategory IN(1,2,3,4)
I suggest to change your code to:
function menuOlustur($ana_kategoriler){
global $db;
/* first - collect all ids */
$ids = array();
foreach ($ana_kategoriler as $kategori) {
$ids[] = $kategori['id'];
}
/* return empty array if there is no ids, or return result of single query matching all results with given ids */
return count($ids) > 0 ? $db->rawQuery('select * from s_kategoriler where kategori IN( ' . implode(",",$ids) . ') AND durum=1 order by sira asc') : array();
}

PHP reproduce exact working sql query but no result

I've got a stored procedure which looks like this:
-- GET INVITES
DROP PROCEDURE IF EXISTS pda.get_invite;
DELIMITER //
CREATE PROCEDURE pda.get_invite ( code varchar(100), invitator_id bigint )
BEGIN
SELECT * FROM pda_invites
WHERE (pda_invites.invitator_id = invitator_id || invitator_id IS NULL)
AND (pda_invites.code = code || code IS NULL);
END //
CALL get_invite ( 'cec95191-23db-11e9-86d7-26374278e97f', NULL );
That works in phpmyadmin and deliver the desired result.
Now on php side, I've got some kind of query builder in a procedure class with registered arguments, which looks like this:
public function toSQL ( ) {
// Make sure params are set
if ( $this->ready == false ) {
throw new Exception ( 'Called unready procedure ' . $this->PROCEDURE_NAME . '.' );
return false;
}
// Build query
$sql= 'CALL ' . $this->PROCEDURE_NAME . '( ';
$i = 0;
foreach ( $this->args as $arg ) {
$param = $this->params[ $i ][ $arg['NAME'] ];
// Apply valid null values
if ( $param == null || $param == 'null' ) {
$sql = $sql . 'NULL';
// Apply varchar strings
} else if ( $arg['TYPE'] == 'varchar' ) {
$sql = $sql . '\'' . $param . '\'';
// Apply numeric values
} else {
$sql = $sql . $param;
}
if ( ($i+1) < $this->args_count ) {
$sql = $sql . ', ';
}
$i++;
}
$sql = $sql . ' );';
return $sql;
}
In my DB Service I trigger that by calling:
$sql = $procedure->toSQL();
$result = $con->query($sql);
echo($sql);
echo json_encode($result);
That results in following equivalent query string which is also reflected by the mysql log:
CALL get_invite( 'cec95191-23db-11e9-86d7-26374278e97f', NULL );
But the problem and question is that it produces an empty result:
{"current_field":null,"field_count":null,"lengths":null,"num_rows":null,"type":null}
Have anyone a clue why it coulds behave this way?

PHP failed to load string from other function as parameter

public function test_passing_string() {
$this - > load - > model(array('registration/Registration_model', 'Jawaban_lab_model'));
$registration = new Registration_model();
$jawaban_lab = new Jawaban_lab_model();
$id = "kuda4";
$jawaban_lab - > load($id); //load jawaban_lab from id
$manualy_written_registration_number = "REG/FM/130102-0001";
echo "registration number from jawaban_lab->registration_number : ".$jawaban_lab - > registration_number
.
"<br> registration number from manualy_written_registration_number : ".$manualy_written_registration_number;
//$registration->load($jawaban_lab->registration_number);
$registration - > load($manualy_written_registration_number);
echo "<br> patient id : ".json_encode($registration - > PatientID);
}
Before go to the question, I will explain my code.
On test_passing_string() function, I call 2 model, and create object for each model there are $registration and $jawaban_lab.
To load data from model I create a load() function. load() has two parameters: column_value and column_name. The default value for column_name is that model's Primary Key.
BUT
The problem comes from
$registration->load($jawaban_lab->registration_number);
I can't retrieve any $registration object data, then I test it by passing the value manually by write this:
$manualy_written_registration_number = "REG/FM/130102-0001";
$registration - > load($manualy_written_registration_number);
And the result appear, doesn't that mean my load() function is fine?
Then I check value inside $jawaban_lab->registration_number by echoing it, surprisingly it display same value as my $manualy_written_registration_number variable.
This is screenshoot in my browser when I run test_passing_string() function:
Using $manualy_written_registration_number value
Using $jawaban_lab->registration_number value
Why can't I use the value from
$jawaban_lab->registration_number even though it has the same value as
my manually writen registraiton number?
public function load($column_value, $column_name = NULL) {
$query = NULL;
if ($column_name != NULL) {
// using custom column.
$query = $this->dbs->get_where($this::DB_TABLE, array(
$column_name => $column_value
));
} else {
// using column primary key .
$query = $this->dbs->get_where($this::DB_TABLE, array(
$this::DB_TABLE_PK => $column_value
));
}
if ($query->row()) {
$this->populate($query->row());
}
}
I use multiple database using CodeIgniter 3, registration_model from SQL server and jawaban_lab from MySQL, jawaban lab have column registration_number to store registration_model primary key
var_dump
First of all thanks to rlanvin and Nirajan N Raju
from rlanvin's comment, i find out the problem is come from codeigniter's query helper, because when i enable codeigniter profiling sql server query return "SELECT CASE WHEN (##OPTIONS | 256) = ##OPTIONS THEN 1 ELSE 0 END AS qi"
so i think codeigniter might be cannot generate query so i create the query manually
i change
public function load($column_value, $column_name = NULL) {
$query = NULL;
if ($column_name != NULL) {
// using custom column.
$query = $this->dbs->get_where($this::DB_TABLE, array(
$column_name => $column_value
));
} else {
// using column primary key .
$query = $this->dbs->get_where($this::DB_TABLE, array(
$this::DB_TABLE_PK => $column_value
));
}
if ($query->row()) {
$this->populate($query->row());
}
}
to this
public function load($column_value, $column_name = NULL) {
$query = NULL;
if ($column_name != NULL) {
$query = $this->dbs->query("SELECT * FROM " . $this::DB_TABLE . " WHERE " . $column_name . " LIKE '" . trim($column_value) . "'");
} else {
$query = $this->dbs->query("SELECT * FROM " . $this::DB_TABLE . " WHERE " . $this::DB_TABLE_PK . " LIKE '" . trim($column_value) . "'");
}
if ($query->row()) {
$this->populate($query->row());
}
}

remove quotes in post values based on array key name

I want to be able to remove quotations from a field on or abouts the name of 'quote'. On post, all my field names and values get matched up and put into an array then enter to the database. Before the SQL is built and after I build the value-key array, how can I single out the field quote, remove the quotation marks that the user inputted, and then add/keep the content in the $values array for my SQL? The questionable area starts with the comment "remove quotes"
public function insertIntoDb($table, $carryUrl = NULL, $ext = '')
{
if (in_array($table, $this->disallow_insert)) {
self::show_error("Inserting into the table '{$table}' is not possible, check the configuration file if this is an error.");
} elseif (!isset($table)) {
self::show_error('Missing `table` parameter in ' . __FUNCTION__);
}
$resultInsert = Nemesis::query("SHOW COLUMNS FROM {$table}");
if (!$resultInsert) {
self::show_error(QUERY_ERROR);
}
$fieldnames = array();
if ($resultInsert->num_rows > 0) {
while ($row = $resultInsert->fetch_array()) {
$fieldnames[] = $row['Field'];
$values = array_intersect_key($_POST, array_flip($fieldnames));
// $values = array_filter($values, function($x) { return $x !== ''; });
// <5.3 $values = array_filter($values, create_function('$x', 'return $x !== "";'));
}
}
// remove quotes for testimonials
if (array_key_exists('quote', array_change_key_case($values, CASE_LOWER))) {
$values['quote'] = preg_replace("/<!--.*?-->/", "", $values); // remove quotes
}
// filter the array
$values = self::filter($values);
$sql = sprintf("INSERT INTO %s (created, created_by, %s) VALUES (NOW(), '$_SESSION[user_id]', '%s')", $table, implode(', ', array_keys($values)), implode("', '", $values));
if ($this->debug) {
echo '<p>' . $sql . '</p>';
} elseif (Nemesis::query($sql)) {
$msg = new Messages();
$msg->add('s', QUERY_INSERT_SUCCESS);
if ($table == 'projects') {
$msg = new Messages();
$msg->add('s', "Information was added to the database. Time to add images!");
}
if (!is_null($carryUrl) && isset($carryUrl)) {
redirect($carryUrl . '?id=' . $_POST['id'] . '&table=' . $table . $ext);
}
} else {
self::show_error(QUERY_ERROR);
}
}
preg_replace is a function that returns a value, not a void. You'll need to assign the returned value back to $values['quote']:
// remove quotes for testimonials
if (array_key_exists('quote', array_change_key_case($values, CASE_LOWER))) {
$values['quote'] = preg_replace("/(\"|')/", "", $values['quote']); // remove quotes
}

query with php array in mysql

I want to fetch contents with multiple filters, right now there's only one.
For Example:
SELECT * FROM Table1 WHERE status=true AND category = 'Camera' AND
model = 'Samsung' AND type = 'New'
I want to create an array for it. But as I'm a newbie in this one not getting a lead.
function getAllRequests($filter){
if(empty($filter)){
$addfilter = '';
}else{
$addfilter = 'AND cat_id=' . $filter;
}
}
$sql = 'SELECT * FROM Table1 WHERE status=true' . $filter;
Any help will be appreciated.
This will get you closer to the solution, though it will not replace the cat_id in the query, which will certainly be wrong - though impossible to do too much more without the array structure:
function getAllRequests($filter)
{
$addfilter="";
if(!empty($filter))
{
foreach($filter as $val)
{
$addfilter. = ' AND cat_id=' . $val .'\'';
}
}
return $addFilter;
}
$myFilters=getAllRequests($filter);
$sql = 'SELECT * FROM Table1 WHERE status=true' . $myFilters;
On the other hand, if your array is strucutred in a way like this:
array{ category => camera, model => samsung); // etc
you could use the following:
function getAllRequests($filter)
{
$addfilter="";
if(!empty($filter))
{
foreach($filter as $key => $val)
{
$addfilter. = " AND `$key` = '$val'";
}
}
return $addFilter;
}
$myFilters=getAllRequests($filter);
$sql = 'SELECT * FROM Table1 WHERE status=true' . $myFilters;
Edit: You can loop through all the filters in the following manner:
function getAllRequests()
{
$addfilter="";
if(!empty($_REQUEST))
{
foreach($_REQUEST as $key => $val)
{
$addfilter. = " AND `$key` = '$val'";
}
}
return $addFilter;
}
$myFilters=getAllRequests();
$sql = 'SELECT * FROM Table1 WHERE status=true' . $myFilters;
You don't need to pass the $_REQUEST (which will work for both GET and POST) as it already a superglobal.
function getAllRequests($filter){
if(empty($filter)){
$addfilter = '';
}else{
$addfilter = 'AND cat_id=' . $filter;
}
}
$sql = 'SELECT * FROM Table1 WHERE status=true' . $addfilter;
You can use another approach, which is using optional parameters and it will make your WHERE clause dynamic as you want. In this approach you pass all parameters' values directly to the sql query which should look like so:
SELECT *
FROM Table1
WHERE 1 = 1
AND (#status IS NULL OR status = #statusParam)
AND (#category IS NULL OR category = #categoryParam)
AND (#model IS NULL OR model = #modelParam)
AND (#type IS NULL OR type = #typeParam)
Then If any of the parameters #statusParam, #categoryParam, #modelParam or #typeParam passed to the query with NULL values, then the comparison with the column holding that value will be ignored. I used the predicate 1 = 1, in case all the values passed to the query with all NULL values in the case all the WHERE clause will be ignored as it won't presented, since WHERE 1 = 1 always true and it will be like SELECT * FROM Table1.
use this
function getAllRequests($filter){
if(empty($filter)){
$addfilter = '';
}else{
$addfilter .= 'AND cat_id=' . $filter;
}
return $addfilter;
}
$sql = 'SELECT * FROM Table1 WHERE status=true' . getAllRequests($filter);
When you are sending array make sure it has indexes
$conditions = array('category' => 'Camera', 'model' => 'Samsung' , 'type' => 'New')
Now loop through it. in your else condition
foreach($conditions as $key =>$value){
$addfilter .= 'AND ' . $key . ' = ' . $value;
}

Categories