Avatar of hrolsons
hrolsonsFlag for United States of America

asked on 

I'm confused what the Question Mark does here

    function getProduct($productId)
    {
      $st = $this->dbConn->prepare("SELECT * FROM tblproduct WHERE id = ?");
      $st->bind_param("i", $productId);
      $st->execute();
      $data = $st->get_result();
      $getProductResult = mysqli_fetch_all($data, MYSQLI_ASSOC);
      $st->close();

      return $getProductResult;
    }

Open in new window

I'm confused what the Question Mark does?  Wildcard?
PHPMySQL Server

Avatar of undefined
Last Comment
arnold
ASKER CERTIFIED SOLUTION
Avatar of tel2
tel2
Flag of New Zealand image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
From the manuals

mysqli

https://www.php.net/manual/en/mysqli.prepare

The statement template can contain zero or more question mark (?) parameter markers⁠—also called placeholders. The parameter markers must be bound to application variables using mysqli_stmt_bind_param() before executing the statement.

PDO

https://www.php.net/manual/en/pdo.prepare.php

The statement template can contain zero or more named (:name) or question mark (?) parameter markers for which real values will be substituted when the statement is executed. Both named and question mark parameter markers cannot be used within the same statement template; only one or the other parameter style. Use these parameters to bind any user-input, do not include the user-input directly in the query.
Avatar of tel2
tel2
Flag of New Zealand image

@Michel,

I hardly know PHP, but is that pdo link appropriate for his mysqli code?  Or is this more applicable:
  https://www.php.net/manual/en/mysqli.prepare
I guess the basics are the same.
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Some history.
When we send a query to the database this can either be a static string OR one we build dynamically using data user input.

This can present some issues around security - the most common one being what is called an SQL injection attack. This is where a malicious user sends data to the server which is then inserted into a query string. The data is constructed in such a way that it "completes" the original query and then adds a malicious query to the end - allowing the attacker to get the script to perform unintended data operations.

Another scenario is where we have to issue the same query multiple times (like an insert) with different data. Rather than recreate the query each time it would be nice if we could tell the db engine that some parts of the query are variables and then to simply provide values for those variables for each iteration.

To solve these (and other issues) the db engine provides something called a prepared statement. This is where a query is constructed with placeholders ('?' in the case of your example). The ? tells the query engine "expect a value to be provided here later".
The code on line 4 is where we "bind" the actual value to the parameter.

From a security perspective this is a much better way of doing it because whatever is bound (line 4) is considered data and can never be used to manipulate the query.

Personally I prefer named parameters with the PDO library. The questions marks are limiting in that
a) They don't tell you anything about what value you are using in that position
b) If you use the same value twice you have to bind it twice
c) The order of the bound parameters is important, which means if you extend the query you can end up with an error if the parameters are not in the right order.

With PDO you would do something like this (assume $conn has already been constructed as a PDO object)
$query = "UPDATE some_table set `name`=:name, `email`=:email WHERE `id`=:id";
$params=['email' => 'john@somedomain.xxx', 'name' => 'John', 'id' => 123];
$stmt = $conn->prepare($query);
$stmt->execute($params);

Open in new window

In  the above query we can see exactly what values we are going to be using and in the $params array (where we supply the actual values) we can add them in any order.

For a situation where you are adding multiple rows you would have something like this
$people = [
 (object)['fullName' => 'John', 'emailAddress => 'john@somedomain.xxx'],
 (object)['fullName' => 'Jack', 'emailAddress => 'jack@somedomain.xxx'],
 (object)['fullName' => 'Jim', 'emailAddress => 'jim@somedomain.xxx']
];

$query = "INSERT INTO some_table (`name`,`email`) VALUES(:name, email)";
$stmt = $conn->prepare($query);

foreach($people as $person) {
  $params=[ 'name' => $person->fullName, 'email' => $person->emailAddress];
  $stmt->execute($params);
}

Open in new window

Avatar of arnold
arnold
Flag of United States of America image

The purpose of the ? As noted by answer and the link is a parametrization that precompike S the query and then can be reused with different choices to speed up the query/response turn around.
It also more secure if you are directly passing data submitted from the browser.
Which ?Julian explain in much greater detail.
PHP
PHP

PHP is a widely-used server-side scripting language especially suited for web development, powering tens of millions of sites from Facebook to personal WordPress blogs. PHP is often paired with the MySQL relational database, but includes support for most other mainstream databases. By utilizing different Server APIs, PHP can work on many different web servers as a server-side scripting language.

125K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo