1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Select result

Discussion in 'PHP' started by piropeator, Dec 15, 2015.

  1. #1
    I want to pass the result of select into an array, I using PDO.
    function listar(){
           $query = "SELECT codigo, nombres FROM prueba";
           $BD = new ConexionDB();
           $recordSet = $BD->prepare($query);
           $recordSet->execute();
    
          // In this part I need help.
          // This part is a old code I need to change this parte.
    
           $lista = array();
           while($fila=$recordSet->FetchRow()) {
              $lista[] = new PruebaVO($fila['codigo'], $fila['nombres']);
           }
           return $lista;
        }
    
    PHP:
    How I do that?
     
    piropeator, Dec 15, 2015 IP
  2. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #2
    If that wrapper is indeed just an extended PDO object (never seen that flavor of the month before), that entire array() garbage isn't even needed... as you can just do a ::fetchAll

    I would suggest losing the "variable for nothing" and using proper names for things instead of just randomly making up your own... You also aren't passing parameters so there's no reason to use the prepare/execute model. This would be the equivalent code:

    function listar(){
    	$db = new ConexionDB();
    	$statement = $db->query('SELECT codigo, nombres FROM prueba');
    	return $statement->fetchAll(PDO::FETCH_ASSOC);
    }
    Code (markup):
    Now that said, I would NOT deploy code like that. You call it more than once or have more than one function working like that you could have multiple connections go unreleased hogging the server since PHP's garbage collection is... wonky. Worse, grabbing an entire result set into an array and returning it as a value is a MASSIVE waste of memory and processing time -- it's just sloppy. I would suggest either passing it a callback function for the output style as needed, or simply returning the actual PDOStatement value to be processed.
     
    deathshadow, Dec 15, 2015 IP
  3. piropeator

    piropeator Well-Known Member

    Messages:
    194
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    121
    #3
    Well, thanks for your answer.
    I using a smarty templates, and for that I use this:
    $lista = array();
           while($fila=$recordSet->FetchRow()) {
              $lista[] = new PruebaVO($fila['codigo'], $fila['nombres']);
           }
    PHP:
    Now, using PDO how I set
    $statement->fetchAll(PDO::FETCH_ASSOC);
    PHP:
    into my PruebaVO?
     
    piropeator, Dec 15, 2015 IP
  4. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #4
    Ah, missed that you were running the result through some form of wasteful object creation thanks to the asshattery that is smarty. You do know that PHP itself is a template system, so why the **** are you running a template system ON TOP OF A TEMPLATE SYSTEM?!? Not a fan... Particularly with the massive code bloat and memory/time wasting asshattery that is Smarty's bread and butter.

    Ok, so fetchAll isn't going to do it and you do "need' to go back to the idiocy of parsing the results into an array; of objects. (RAM? who needs it!)

    Assuming you are on some crappy older version of PHP (pre 5.5):

    $result = array();
    	while ($row = $statement->fetch(PDO::FETCH_ASSOC) {
    		$result[] = new PruebaVO($row['codigo'], $row['nombres']);
    	}
    	return $result;
    Code (markup):
    Intermediate PHP (5.4+) you could say [] instead of array()

    If you are on a modern PHP (5.6 or 7) you can use the generator syntax to throw most of the overhead in the bin by axing the array and the return function.

    while ($row = $statement->fetch(PDO::FETCH_ASSOC) {
    	yield new PruebaVO($row['codigo'], $row['nombres']);
    }
    Code (markup):
    Either way though that's grossly inefficient which is why I wouldn't deploy any of that, and would kick that "smarty" idiocy to the curb if for no other reason than it quadrupling your memory footprint and taking twice as long to run. It's another of those things like bootstrap or jQuery that leaves me wondering just what the **** is in that kool-aid that is powerful enough to delude people into thinking they serve a purpose.
     
    deathshadow, Dec 16, 2015 IP
  5. piropeator

    piropeator Well-Known Member

    Messages:
    194
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    121
    #5
    Thanks and this is my final code:
    function listar(){
           $query = "SELECT codigo, nombres FROM prueba";
           $BD = new ConexionDB();
           $recordSet = $BD->prepare($query);
           $recordSet->execute();
           $fila = $recordSet->fetchAll();
            $lista = array();
    
            while ($row = $fila->fetch(PDO::FETCH_ASSOC)) {         //<------- here is the Fatal error
                    $lista[] = new PruebaVO($fila['codigo'], $fila['nombres']);
            }
           return $lista;
        }
    
    PHP:
    I have this message:
    Fatal error: Call to a member function fetch() on a non-object in
    HTML:
    What is the error?
     
    piropeator, Dec 17, 2015 IP
  6. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #6
    ->fetch replaces the fetchall, you've got it operating upon it... and you're indexing the wrong values.

    function listar() {
    	$query = "SELECT codigo, nombres FROM prueba";
    	$BD = new ConexionDB();
    	$recordSet = $BD->prepare($query);
    	$recordSet->execute();
    	$lista = array();
    
    	while ($row = $recordSet->fetch(PDO::FETCH_ASSOC)) {
    		$lista[] = new PruebaVO($row['codigo'], $row['nombres']);
    	}
    	return $lista;
    }
    Code (markup):
    That was partly a "my bad" on the original, I didn't notice you were turning it into a array of objects... something I'd never be doing in the first place.

    Again though, you've got the variable for nothing and aren't passing any parameters, so there is NO reason to be using prepare/execute. You only use that model when passing values to the query... as such there's no reason for that to be much more than:

    function listar() {
    	$db = new ConexionDB();
    	$statement = $db->query('SELECT codigo, nombres FROM prueba');
    	$lista = array();
    	while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
    		$lista[] = new PruebaVO($row['codigo'], $row['nombres']);
    	}
    	return $lista;
    }
    Code (markup):
    Though that's for ancient PHP (5.3/earlier). For 5.4/newer that's:
    function listar() {
    	$db = new ConexionDB();
    	$statement = $db->query('SELECT codigo, nombres FROM prueba');
    	$lista = [];
    	while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
    		$lista[] = new PruebaVO($row['codigo'], $row['nombres']);
    	}
    	return $lista;
    }
    Code (markup):
    and as of 5.6 a function that simple can use "generators" with the very cool "yields" statement thus:

    function listar() {
    	$db = new ConexionDB();
    	$statement = $db->query('SELECT codigo, nombres FROM prueba');
    	while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
    		yield new PruebaVO($row['codigo'], $row['nombres']);
    	}
    }
    Code (markup):
    "Yield" is one of those "Well it's about time!" additions to PHP 5.6 and 7.

    ... and again, TRY to stick to the naming conventions used on PHP.NET for your variable names so other developers have some clue what you are doing. The result is a PDOStatement so it's $statement or $stmt, not $recordSet.
     
    deathshadow, Dec 17, 2015 IP
  7. piropeator

    piropeator Well-Known Member

    Messages:
    194
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    121
    #7
    How do you work a php MVC project?
     
    piropeator, Dec 21, 2015 IP
  8. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #8
    I don't, PHP isn't event driven so MVC can't be done properly in it and ends up a bloated mess in systems that try to do it.

    I agree there should be separation of input processing, data access and output, but without being event driven trying to do that with MVC ends up a slow nonsensical mess. It ALMOST made sense to at least try back when database connections were inherently global in scope using the outdated mysql_ functions, but even then it just seemed to waste time dicking around taking simple tasks and making them needlessly complex.

    Ah, I see, your quote is a bit mangled... You asked more than just that.

    The reason I avoid fetchAll is it wastes memory and processing time making a complete copy of data that's already in memory. Boom you just doubled the memory footprint of the results. It's why a LOT of these "frameworks" you'll find and worse, "template systems" annoy me no end as they replicate existing functionality and double or more the memory footprint... yet again you'll find hordes of people proclaiming how much "easier" they are.

    One difference - array declaration, in newer PHP you only have to say [] instead of array().
     
    deathshadow, Dec 21, 2015 IP
  9. piropeator

    piropeator Well-Known Member

    Messages:
    194
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    121
    #9
    function listar() {
        $db = new ConexionDB();
        $statement = $db->query('SELECT codigo, nombres FROM prueba');
        $lista = [];
        while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
            $lista[] = new PruebaVO($row['codigo'], $row['nombres']);
        }
        return $lista;
    }
    PHP:
    To avoid overloading the memory, it is possible create a __construct() and __destruct() ??
     
    piropeator, Jan 30, 2016 IP