Need to show the same array twice

Discussion in 'PHP' started by qwikad.com, Sep 3, 2014.

  1. #1
    I need to show this array again, but when I copy and paste it for some reason it's not showing. Thank you for any / all help.



    <?php
    if (@mysql_num_rows($pres))
    {
    $i = 0;
    ?>
    <?php
    while ($row = mysql_fetch_array($pres))
    {
    $i++;
    $imgsize = GetThumbnailSize("{$datadir[adpics]}/{$row[picfile]}", $tinythumb_max_width, $tinythumb_max_height);
    ?>
    <img src="/timthumb.php?src=<?php echo "{$datadir[adpics]}/{$row[picfile]}"; ?>&w=590" id="adimg<?php echo $i; ?>" width="<?php echo $imgsize[0]; ?>" height="<?php echo $imgsize[1]; ?>">
    
    <?php } ?>
    <?php } ?>
    Code (markup):
     
    qwikad.com, Sep 3, 2014 IP
  2. sarahk

    sarahk iTamer Staff

    Messages:
    28,897
    Likes Received:
    4,553
    Best Answers:
    123
    Trophy Points:
    665
    #2
    Yikes, you shouldn't be using mysql_ anyway

    Find yourself a database layer that returns a normal array when you do a query then there will be no problems with reusing the array over and over again.
     
    sarahk, Sep 4, 2014 IP
  3. PoPSiCLe

    PoPSiCLe Illustrious Member

    Messages:
    4,623
    Likes Received:
    725
    Best Answers:
    152
    Trophy Points:
    470
    #3
    There are so many things wrong with that code... Mixing a counter with a while, using mysql_ instead of mysqli_ or PDO, opening and closing PHP every other line...
    As for the reuse of the array, this has to do with the position of the cursor in the query. Look into reseting the mysql cursor - so long since I've used this, I can't recall the exact code.
     
    PoPSiCLe, Sep 4, 2014 IP
  4. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,373
    Likes Received:
    1,720
    Best Answers:
    31
    Trophy Points:
    475
    #4
    Guys I didn't come up with any of that. And yes it's a very old code. If I have to redo all the snippets it will be countless hours of work (I will have to hire someone to do that).

    Did you mean it has something to do with mysql_data_seek? I can't figure out how to implement it. Need further assistance.
     
    qwikad.com, Sep 4, 2014 IP
  5. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,373
    Likes Received:
    1,720
    Best Answers:
    31
    Trophy Points:
    475
    #5
    How Sarahk, how?
     
    qwikad.com, Sep 4, 2014 IP
  6. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,373
    Likes Received:
    1,720
    Best Answers:
    31
    Trophy Points:
    475
    #6
    Got it working. Just added mysql_data_seek($pres,0); and all went well.
     
    qwikad.com, Sep 4, 2014 IP
  7. sarahk

    sarahk iTamer Staff

    Messages:
    28,897
    Likes Received:
    4,553
    Best Answers:
    123
    Trophy Points:
    665
    #7
    sarahk, Sep 4, 2014 IP
  8. qwikad.com

    qwikad.com Illustrious Member Affiliate Manager

    Messages:
    7,373
    Likes Received:
    1,720
    Best Answers:
    31
    Trophy Points:
    475
    #8
    Yeah, I got it working. Databases and what-not is not my forte.

    I am sure I am still going to hear from deathshadow yet as to how retarded, idiotic, moronic that snippet is and that I, as a person, shouldn't even exist since I use something so archaic. Ha.
     
    qwikad.com, Sep 4, 2014 IP
    sweetpea69 likes this.
  9. nico_swd

    nico_swd Prominent Member

    Messages:
    4,153
    Likes Received:
    344
    Best Answers:
    18
    Trophy Points:
    375
    #9
    While I'm troubled by most things that were already mentioned, I'm mostly worried about something else here.

    Why waste MySQL resources when you can save the fetched results into an array, which you can later use to display the same data again?

    And if GetThumbnailSize() does what I think it does, you probably shouldn't call it more than once for each image... ever! That means, save the dimensions in the database the moment you upload the picture.
     
    nico_swd, Sep 4, 2014 IP
  10. sarahk

    sarahk iTamer Staff

    Messages:
    28,897
    Likes Received:
    4,553
    Best Answers:
    123
    Trophy Points:
    665
    #10
    Gawd, that wasn't what I meant, I figured he could be positive and point you in the right direction so that if you make changes you get it right.
     
    sarahk, Sep 4, 2014 IP
    malky66 likes this.
  11. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,999
    Best Answers:
    253
    Trophy Points:
    515
    #11
    I wouldn't go that far -- but you do need the riot act read to you AGAIN about using the mysql_ functions.

    Though IF you are going to use the outdated, deprecated and soon no longer to even be supported functions, what you are looking for is this:
    http://php.net/manual/en/function.mysql-data-seek.php

    Just do:
    mysql_data_seek($result, 0);

    before the second loop to reset the pointer to the beginning of your result set.

    Though really, WHY are you using the insecure and out of date mysql_ functions, WHY are you endlessly opening and closing PHP for no good reason, why are you suppressing the number of rows error, and that ridiculously silly string construction?!? I do however get why you have a counter... that actually makes sense since you won't have a sequential order inside the fetch unless you did something stupid like generated it in the query.

    <?php
    
    if ($pres && mysql_num_rows($pres)) {
    	$i = 0;
    	while ($row = mysql_fetch_array($pres)) {
    		$imageLink = $datadir['adpics'] . '/' . $row['picfile'];
    		$imageSize = GetThumbnailSize(
    			$imageLink,
    			$tinythumb_max_width,
    			$tinythumb_max_height
    		);
    		echo '
    			<img
    				src="/timthumb.php?src=', $imageLink, '&w=590"
    				id="adimg', ++$i, '"
    				width="', $imgsize[0], '"
    				height="', $imgsize[1], '"
    			/>';
    	}
    	// so you can loop it again later
    	mysql_data_seek($pres, 0); 
    }
    
    ?> 
    Code (markup):
    Though really you should be using something like PDO with cursors.

    <?php
    
    /*
    	assuming $stmt is a PDOStatement that was initialized as
    	$stmt = $db->prepare($query, [
    		PDO:ATTR_CURSOR => PDO::CURSOR_SCROLL
    	]);
    */
    
    if ($stmt) {
    	$i = 0;
    	if ($row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_FIRST)) do {
    		$imageLink = $datadir['adpics'] . '/' . $row['picfile'];
    		$imageSize = GetThumbnailSize(
    			$imageLink,
    			$tinythumb_max_width,
    			$tinythumb_max_height
    		);
    		echo '
    			<img
    				src="/timthumb.php?src=', $imageLink, '&w=590"
    				id="adimg', ++$i, '"
    				width="', $imgsize[0], '"
    				height="', $imgsize[1], '"
    			/>';
    	} while ($row = $stmt->fetch(PDO::FETCH_ASSOC));
    }
    
    ?> 
    Code (markup):
    The nice part about that approach is you can use that same code as many times as you like in your output and it will always work, because the first call inside the 'if' ALWAYS resets the pointer to the start of the result set, while the "while" retrieves them normally. PDO cursors are nice because you can random-access AND even iterate through them backwards by simply changing PDO::FETCH_ORI_FIRST to PDO::FETCH_ORI_LAST and appending PDO::FETCH_ORI_PRIOR to the ::fetch thats on the do/while. I've had a few cases where database output needed to be forward order at the top of the page and reverse order at the bottom, and PDO cursors saved a lot of headaches (and memory overhead) thanks to that.

    NOT that I'd EVER have PHP outputting my thumbnails directly as the only means of access; I prefer to use a 404 handler when attempting to call a thumbnail to trap the call and generate the thumb. First attempt 404 you have PHP output the thumb AND make the file. Second attempt the file will exist so no 404. It's a slick way of handling it. Likewise I'm not wild about the overhead that the imagesize function introduces to page loads. Depending on your traffic levels the way you are pulling the image sizes can bite you in the ass VERY quickly in terms of memory and CPU use on the server as you are making the server actually have to load those images and parse their headers.

    Just something to consider.
     
    deathshadow, Sep 6, 2014 IP
    sweetpea69 and qwikad.com like this.
  12. pmf123

    pmf123 Notable Member

    Messages:
    1,449
    Likes Received:
    81
    Best Answers:
    0
    Trophy Points:
    215
    #12
    someone should create a site you can enter old php code with mysql_ functions and it automatically updates it with the PDO commands....
     
    pmf123, Sep 19, 2014 IP
    qwikad.com likes this.
  13. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,999
    Best Answers:
    253
    Trophy Points:
    515
    #13
    Sadly it's not a 1:1 that I think could be automated. The conversion from "blindly dumping variables into a query string like a dumbass" to "using prepared queries" isn't one that's easy to determine -- much less that not all mysql_query would be prepare/execute since queries without user variables would be ->query or ->exec and not prepare/execute.

    For example if all you were doing is a fixed
    SELECT *
    FROM default_permissions
    Code (markup):
    You'd use PDO::query as there is no variables being passed, but there would be a result set.

    Whereas if all you were doing is:
    UPDATE tracking
    SET lastaccess= NOW()
    Code (markup):
    You'd use PDO::exec as there are neither variables passed to it or a returned result set

    ... but if you were doing:
    UPDATE users
    SET lastaccess = NOW()
    WHERE id = ?
    Code (markup):
    You'd use PDO::prepare with PDOStatement::execute([$userId]) since that's the PROPER way of passing variables to a query...

    ...well unless you're trying to do something jacktarded like passing the table name as a variable; Something only utilities like phpMyAdmin or your initial installer should even THINK about trying to do, and that 99.99% of CMS or other PHP software has no damned business even going near in their actual runtimes!

    The complete lack of anything even remotely resembling PDO::prepare and PDOstatement::execute in the old mysql_ functions is the real hangup; it's a change in coding philosophy and design that means a manual rewrite as I can't see automation EVER getting that conversion correct.

    I mean seriously, converting this type of asshattery:

    $userId = mysql_real_escape_string($_POST['id']);
    $query = "SELECT * FROM userdata WHERE id = $userId";
    mysql_query($query);
    Code (markup):
    to:

    $statement = $db->prepare('SELECT * FROM userdata WHERE id = ?');
    $statement->execute([$_POST['id']);
    Code (markup):
    Might seem simple, but it falls apart when you take into account all the

    Automatically, with all the different ways people might be declaring that query string?

    Though I see one more dumbass:
    $query = "SELECT * FROM userdata WHERE id = " . $userId;
    Code (markup):
    I'm punching someone in the face. Either use double-quotes or don't people.
     
    Last edited: Sep 19, 2014
    deathshadow, Sep 19, 2014 IP
  14. Krellen

    Krellen Greenhorn

    Messages:
    38
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    18
    #14
    I won't reiterate what everyone else has already said about some of the poor coding. But to answer your question directly, if you want to reuse the mysql results array, just do something like this instead:

    $data = array();
    while ($row = mysql_fetch_array($pres))
    {
        $data[] = $row;
    }
    Code (markup):
    Now you can loop over $data using foreach() and it will have all your rows:

    foreach ($data as $key => $row) 
    {
        // whatever
    }
    Code (markup):
    As a side benefit, $key will be your counter (-1, as array indexes start at 0).
     
    Krellen, Sep 19, 2014 IP
  15. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,999
    Best Answers:
    253
    Trophy Points:
    515
    #15
    Too bad that's poor coding as it's making a second copy of the result set in memory. Fatter footprint and slower.

    Hence:
    while ($row = mysql_fetch_array($result)) {
      // first time
    }
    mysql_data_seek($result, 0);
    while ($row = mysql_fetch_array($result)) {
      // second time
    }
    Code (markup):
    You don't brute force something there's already a command to do; and creating extra copies of result sets is just as crappy as creating "variables for nothing".
     
    deathshadow, Sep 20, 2014 IP
    qwikad.com likes this.
  16. Krellen

    Krellen Greenhorn

    Messages:
    38
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    18
    #16
    As always, there are many ways to do similar things that achieve effectively the same results in the end. I definitely wouldn't say using a results array is "poor coding" or "brute forcing". This is done literally all the time in programming and has very tangible benefits especially when you need to do anything with the result data beyond a simple loop - which is about all a while($row=mysql_fetch_array()) is good for.

    Also, if you're worried about MySQL's result memory usage and creating "copies" of result sets, see mysql_free_result().

    Of course a full results array isn't best for every situation, especially for huge datasets, but it's an important possible solution the poster should be aware of, rather than relying on putting mysql_data_seek and mysql_fetch_array all over the place.
     
    Krellen, Sep 20, 2014 IP