Asked  1 Year ago    Answers:  5   Viewed   6 times

The full question should be "Is this correct or is it some bug I can't count on?"

WHY is this correct behavior?

I've been working with PDO more and in particular playing with fetching data directly into objects. While doing so I discovered this:

If I fetch data directly into an object like this:

$STH = $DBH->prepare('SELECT first_name, address from people WHERE 1');
$obj = $STH->fetchAll(PDO::FETCH_CLASS, 'person');

and have an object like this:

class person {
  public $first_name;
  public $address;

  function __construct() {
    $this->first_name = $this->first_name . " is the name";
  }
}

It shows me that the properties are being assigned before the __construct is being called -- because the names all have " is the name" appended.

Is this some bug (in which case I can't/won't count on it) or is this The Way It Should Be. Because it's really quite a nice thing the way it works currently.

Update

Apparently, according to one of the maintainers this is not a bug. Someone posted it as a bug in 2008, to which the reply was 'its not a bug, read the docs'.

However, I'd really like to know WHY this is correct behavior.

 Answers

1

After much reading I think I finally came across the answer: it works this way intentionally, and you have the option of making it operate otherwise.

There's a mostly undocumented PDO constant called PDO::FETCH_PROPS_LATE which you can use to cause the properties to be fetched into the object after its been constructed. For example:

$obj = $STH->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'person');

Will cause the properties to be assigned AFTER the object is created, so my example above would not modify the properties at all. Leaving the PDO::FETCH_PROPS_LATE off, of course, causes it to act as described in my example in the original question.

The maintainers seem to have actively considered that both behaviors may be desirable and given you the option to do either. The documentation doesn't even explain it -- I was reading through a list of PDO constants and saw it, and gave it a shot.

Saturday, May 29, 2021
 
5

PDO does not escape the variables. The variables and the SQL command are transferred independently over the MySQL connection. And the SQL tokenizer (parser) never looks at the values. Values are just copied verbatim into the database storage without the possibility of ever causing any harm. That's why there is no need to marshall the data with prepared statements.

Note that this is mostly a speed advantage. With mysql_real_escape_string() you first marshall your variables in PHP, then send an inefficient SQL command to the server, which has to costly segregate the actual SQL command from the values again. That's why it's often said that the security advantage is only implicit, not the primary reason for using PDO.

If you concat the SQL command and don't actually use prepared statments (not good!), then yes, there still is an escape function for PDO: $pdo->quote($string)

Thursday, April 1, 2021
 
Jesse
 
5

As stated in another question on SO (relative since it is about hidden inputs) :

The browsers are OK with it. However, how the application library parses it may vary.
Programs are supposed to group identically named items together. While the HTML specification doesn't explicitly say this, it is implicitly stated in the documentation on checkboxes.

So this is just pure luck : Working with another server-side technology may get you another result.

For more information about what you could get, check this answer on another question. It has a lot of useful information and specs.


Besides, if you wanted to get all the values of name="first", you would better name them like name="first[]".

Then you will have on the server $_POST["first"] as an array you can loop through.

Saturday, May 29, 2021
 
CAMason
 
5

Well, at second glance your question looks more complex to be answered with just one link

How does php pdo's prepared statements prevent sql injection?

How can prepared statements protect from SQL injection attacks?

What are other pros/cons of using PDO?

Most interesting question.
A greatest PDO disadvantage is: it is peddled and propagated a silver bullet, another idol to worship.
While without understanding it will do no good at all, like any other tool.
PDO has some key features like

  • Database abstraction. It's a myth, as it doesn't alter the SQL syntax itself. And you simply can't use mysql autoincremented ids with Postgre. Not to mention the fact that switching database drivers is not among frequent developer's decisions.
  • Placeholders support, implementing native prepared statements or emulating them. Good approach but very limited one. There are lack of necessary placeholder types, like identifier or SET placeholder.
  • a helper method to get all the records into array without writing a loop. Only one. When you need at least 4 to make your work sensible and less boring.

Does using PDO reduce efficiency?

Again, it is not PDO, but prepared statements that reduces efficiency. It depends on the network latency between the db server and your application but you may count it negligible for the most real world cases.

Sunday, July 18, 2021
 
ajreal
 
4

Here is what I managed to figure out:

Constants

  • PDO::FETCH_OBJ
    Is used to fetch into a new instance of an unnamed ("anonymous") object

  • PDO::FETCH_CLASS
    Is used to fetch into a new instance of an existing class (the column names should match existing properties, or __set should be used to accept all properties). The constructor of the class will be called after the properties are set.

  • PDO::FETCH_CLASSTYPE
    Used with FETCH_CLASS (bitwise OR), the name of the class to create an instance of is in the first column, instead of supplied to the function.

  • PDO::FETCH_INTO
    Is used with the same type of class as FETCH_CLASS (must handle all columns as property names), but updates an existing object as opposed to creating a new one.

  • PDO::FETCH_LAZY
    I don't know what this does.

Functions

  • PDOStatement::fetch
    The regular get-a-row command. I don't know how to use this with FETCH_CLASS or FETCH_INTO since there does not be any way to pass the class name/instance.

  • PDOStatement::fetchObject
    A way to do FETCH_CLASS or FETCH_INTO, including passing constructor args. With no args is a shorthand for FETCH_OBJ.

  • PDOStatement::setFetchMode
    A way to set the default fetch mode, so that PDOStatment::fetch can be called without args.


That is the best I managed to figure out. I hope it helps someone else (I needed the fetchObject method)

Thursday, July 29, 2021
 
coolguy
 
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :