bindParam as function argument doesn't pass value - php

I have a question, namely - I have created a function that selects certain things from the base. I passed the function argument as bindParam, but I get an empty array. The only way in this case is to insert a variable from the argument directly into the query without binding. What is the reason for this?
function sampleFunction($test, $test2, $db) {
$stmt = $db->prepare("SQL QUERY WITH :test AND :test2");
$stmt->bindParam(':test', $test);
$stmt->bindParam(':test2', $test2);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $result;
}

Related

How to use Reflection to insert data with mysqli by bind_param method? what is difference of these two arrays?

As bind_param($types, $var1, $var2, $var3,..) method of mysqli_stmt class it gets just a series of $variables after second parameter (I want to pass array there), and the number of $variables is unknown in my case, I want to use Reflection in my insert($data) function. http://php.net/manual/ru/mysqli-stmt.bind-param.php
I do not show the unnecessary part of my function, to avoid confusion...
public function insert($data)
{
$types = 'sss';
$values = array_values($data);
Removed unrelated code
$ref = new ReflectionClass($this->stmt);
$method = $ref->getMethod("bind_param");
//array_unshift($values,$types); 1-option
$values = array($types,'alex','alex#code.com','cats'); 2-option
$method->invokeArgs($this->stmt, $values);
$done = $this->stmt->execute();
$this->stmt->close();
return $done;
}
As shown in
$method = $ref->getMethod("bind_param");
$method->invokeArgs($this->stmt, $values);
In this part I use Reflection to pass array to second parameter of bind_param() method of $this->$stmt object.
$method->invokeArgs($this->stmt, $values);
It doesn`t make mysqli insert into table with 1-option.
But mysqli inserts data when I use 2-option. Why? I have to use with 1-option as number of parameters is unknown.
How can I benefit from Reflection and mysqli it?
What is the difference between those two options(arrays)?
You can use splat operator (PHP version >= 5.6):
public function insert($data)
{
$stmt = $this->link->prepare($sql);
$stmt->bind_param(str_repeat('s', count($data), ...$data);
$stmt->execute();
}

How can I write a PHP function that takes an arbitrary number of parameters?

I am trying to find a way to create a function in PHP that will wrap a SQL query given in the parameter so that I can prevent SQL Injection in the function that can then be called many times throughout my application. Rather than repeating the same statements for each and every query.
For example say I have the following PHP code that prepares and executes a query to prevent SQL injection:
$name = "$_POST['name']";
$stmt = $db->prepare('SELECT * FROM test_table WHERE test_name = ?');
$stmt->execute(array($name));
For each query my application will need to make these statements will need to be repeated. I want a way to prevent having to do this each time, rather I would simply want to call a function each time and pass in the query.
How would I wrap this in a function that can then be called whenever I need to make a query in my application, given that I do not know in advance the amount of parameters that would need to be parameterized. The above query has one parameterized query, but each query may have a different amount.
Note:
I am using PDO statements
Something like this:
public function query($query)
{
// statements here
}
Where the query is passed in as a parameter.
Does anyone know how I can achieve this?
Currently, I am using something like this that might work for you.
Example:
function superQuery($query, $params, $type = null) {
$pdo = new pdo(...);
$stmt = $pdo->prepare($query);
$stmt->execute($params);
if ($type === "select") {
$result = $stmt->fetchAll();
return $result;
} else {
return $stmt;
}
$query = "SELECT row FROM column WHERE row1 = ? AND row2 = ?";
$params = [$row1, $row2];
$type = "select";
$row = selectQuery($query, $params, $type);
// returns multidimensional array or true/false depending if argument is used //
There's lots of ways you can do it. You could also pass a count argument if you wanted to return a count instead of a result set. But hopefully this points you in the right direction and gives you some ideas.

Converting an object to a string - php pdo

I'm fetching some data and trying to print it to the page but i'm getting the following error -
PHP Catchable fatal error: Object of class PDOStatement could not be converted to string
This is my query function;
function query($query, $bindings, $conn)
{
$stmt = $conn->prepare($query);
$stmt->execute($bindings);
return $stmt;
}
the query and printing to the page;
$testimonials = query ('SELECT * FROM testimonials ORDER BY id = :id DESC LIMIT 1',
array('id' => ['id']), $conn);
print $testimonials;
I'm not sure how I can turn it to a string without re-writing the function or should I be doing that?
You are not actually returning any results, you're returning the PDO object
change the return from
return $stmt;
to
return $stmt->fetchAll(PDO::FETCH_ASSOC);
this will return multiple results (if they are available)
or
return $stmt->fetch(PDO::FETCH_ASSOC);
will return a single result
UPDATE
To answer your comment, you can use
return ($stmt->rowCount() > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;
Note: this will return an array, which means you need to access the array to print what you want.. you can do this like so:
foreach( $testimonials as $testimonial )
{
print( $testimonial['field_name_from_database'] );
}
it should be,
print_r($testimonials);
For debug/test purpose, it's better to use var_dump(), it provide an html formated output with additionnal informations (type, length) and work recursively.
Also you return a PDOStatement object, it's a prepared request that havent been executed. You need it to fetch the results (fetch or fetchAll).
PHP :
function query($query, $bindings, $conn)
{
$stmnt = $conn->prepare($query);
$stmt->execute($bindings);
return $stmt->fetchAll();
}

PHP MySQLi prepared statements and fetching subset of columns

I am using MySQLi and PHP to call a stored MySQL routine with prepared statements. It returns a result set with dozens of columns.
$stmt = $dbconnection->prepare("CALL SomebodysDbProcedure(?);");
$stmt->bind_param("s", $idvalue);
$stmt->execute();
$stmt->bind_result($col1, $col2, $col3, ...);
However, I am only interested in a subset of the output columns.
The documentation says bind_result() is required to handle the complete set of returned columns:
Note that all columns must be bound after mysqli_stmt_execute() and
prior to calling mysqli_stmt_fetch().
Do I need to add code also for those columns I'm uninterested in? If so the application will break if the MySQL stored routine result set is expanded in the future, or even columns rearranged. Is there a workaround for this?
I'm assuming that you just don't want to write out all those variables for the bind_result() function. You could use a function like below instead of the bind_result() function. Pass it your $stmt object and you'll get back an array of standard objects with the fields you want.
function getResult($stmt)
{
$valid_fields = array('title', 'date_created'); // enter field names you care about
if (is_a($stmt, 'MySQLi_STMT')) {
$result = array();
$metadata = $stmt->result_metadata();
$fields = $metadata->fetch_fields();
for (; ;)
{
$pointers = array();
$row = new \stdClass();
$pointers[] = $stmt;
foreach ($fields as $field)
{
if (in_array($field->name, $valid_fields)) {
$fieldname = $field->name;
$pointers[] = &$row->$fieldname;
}
}
call_user_func_array('mysqli_stmt_bind_result', $pointers);
if (!$stmt->fetch())
break;
$result[] = $row;
}
$metadata->free();
return $result;
}
return array();
}
The answer of Jonathan Mayhak guided me in the right direction. On PHP bind_result page, nieprzeklinaj provides a function called fetch(). It works; use it like this:
$stmt = $conn->prepare("CALL SomebodysDbProcedure(?);");
$stmt->bind_param("s", $idvalue);
$stmt->execute();
$sw = (array)(fetch($stmt));
$s = $sw[0]; // Get first row
$dateCreated = $s['date_created']; // Get field date_created
Edit: Unfortunately successive calls within the same PHP file don't seem to work with this method.
Try using fetch_fields php method:
array mysqli_fetch_fields ( mysqli_result $result )
http://php.net/manual/en/mysqli-result.fetch-fields.php

using an empty array as a parameter for execute

I was reader about PDO , and I was wondering what is the deference between those two methods:
public function query($sql)
{
$req = $this->db->prepare($sql);
$req->execute();
return $req->fetchAll(PDO::FETCH_OBJ);
}
public function query($sql, $data = array())
{
$req = $this->db->prepare($sql);
$req->execute($data);
return $req->fetchAll(PDO::FETCH_OBJ);
}
In the second method, execute has an empty array as a parameter and the first one doesn't, what is the role of using an empty array as a parameter for execute ?
The array is only empty by default. You can pass values in that array and they will be inserted into your SQL statement appropriately (ie - array key=>field name).
Defining an empty array in the function parameters states that this is an optional parameter and you are not forced to pass it - only when it is relevant. For example, when performing an INSERT command. If you don't pass any value to the $data parameter, it's default value will simply be an empty array.
An example of using default parameters -
function saySomething($text="Hello World!"){
echo $text;
}
saySomething(); // will echo out the default "Hello World!"
saySomething("Goodbye World!"); // will echo out "Goodbye World!" as specified.
First one lets you to run a query without parameters.
Second one lets you to run a query either with parameters or without:
$data = $db->query("SELECT * FROM table");
$data = $db->query("SELECT * FROM table WHERE id=?",array($id));
both works.
You can add you parameter bindings in an array instead of using the bindParam() function beforehand.
for instance you wanna select something by id
$stmt = $dbh->prepare("SELECT * FROM `something` WHERE `id` = ?");
$stmt->execute(array($id));
is the same as
$stmt = $dbh->prepare("SELECT * FROM `something` WHERE `id` = ?");
$stmt->bindParam(1, $id, PDO::PARAM_INT, 11);
$stmt->execute();
Though for the bindParam function you can check better,
Check PHP Manual PDO::excute()

Categories