We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 33675
    • 4 Posts
    Not sure if I'm posting in the correct forum, I've been playing around with MODx on and off for a couple years. My ultimate goal is to implement it on a site that I maintain (http://www.boxtorow.com) but for now, it's all running on my localhost. I'm using a Windows Vista laptop with WAMP Server (Apache 2.2.11, PHP 5.3.0, MySQL 5.1.36) and MODx Revolution 2.2.4-pl (traditional).

    I have a custom database table essentially recreating the information in this HTML table: http://boxtorow.com/affiliates.php. I want to pull the three most recent records and display the station name and city. I found out not too long ago when I updated my version of Revo that it preferred using PDO as opposed to typical MySQL statements. I played around with it and got the FETCH_ASSOC to work as I intended but now I'm getting a warning just below the result set on the page saying:

    Warning: mysql_free_result() expects parameter 1 to be resource, object given in...

    and

    Warning: mysql_close(): no MySQL-Link resource supplied in...

    Both warnings reference the file \core\cache\includes\elements\modsnippet\3.include.cache.php, if that makes any difference.

    What can I do to fix this error? Can somebody help? I did some searching for PDO and free_result and came up with PDOStatement::closeCursor() and settnig the object to null but so far as I've tried, nothing has worked. I'm somewhere between beginner and novice when it comes to all this so it's giving me a headache. But I'd like to get it working properly eventually. Since boxtorow is a fairly large site, I'd love to get it running solely on MODx. I already know the Scoreboard is going to be a doozy of a project but I figure I'd learn a lot about PHP/MySQL and MODx by getting it all to work.

    But anyway, any help with this PDO::FETCH_ASSOC and these mysql_free_result() and mysql_close() warnings would be greatly appreciated. If I need to post the code or attach any files, please let me know.

    Thanks!

    zC

    This question has been answered by dunnock. See the first response.

      • 28042 ☆ A M B ☆
      • 24,524 Posts
        Studying MODX in the desert - http://sottwell.com
        Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
        Join the Slack Community - http://modx.org
        • 42602
        • 81 Posts
        You cannot use any mysql_ commands, nor mysqli_ with PDO. The close cursor is absolutely the right thing to do. To fix all the errors, remove all mysql_ commands first.

        Basic example of PDO usage with xPDO/MODx if you want to go around the xPDOQuery layer:

        //Directly with query
        $q = "SELECT something.id FROM some_table WHERE id = 1";
        while ($modx->pdo->query($q) as $row) {
           
        }
        
        // With prepared statement (lot safer generally
        $q = "SELECT something.id FROM some_table WHERE id = :id";
        $stmt = $modx->pdo->prepare($q);
        $stmt->execute(array(':id' => 1));
        foreach($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
            
        }
        $stmt->closeCursor();
        


        The closeCursor is not required if you loop through the whole result set usually.

        Sipping my morning coffee so brain not functioning completely. So do ask more if I am confusing (especially if I just wrote loads of hmmmm)
          • 22303 MODX Staff
          • 10,725 Posts
          Actually, $modx->query and $modx->prepare() are the proper methods to use. Accessing the pdo object directly is not recommended in xPDO. Besides, by using the modX equivalent wrapper methods for PDO, you get on-demand connections. In order to access $modx->pdo, you must already have a connection.
            • 33675
            • 4 Posts
            This is definitely some great feedback... thanks to all.

            So here's my code as it currently stands (before I posted this question yesterday). What would any of you recommend as best practice and personally, I love the simplest approach possible. But if it absolutely needs to be complex, so long as I can follow what's going on without too much of a headache, I'm good. I appreciate all the help.

            <?php
            function elements_modsnippet_3($scriptProperties= array()) {
            global $modx;
            if (is_array($scriptProperties)) {
            extract($scriptProperties, EXTR_SKIP);
            }
            // Make the query
            // $result = $modx->db->query('SELECT * FROM b2rmodx2.b2rmodx2_station_affiliates ORDER BY id ASC LIMIT 3');
            $result = $modx->query('SELECT * FROM b2rmodx2.b2rmodx2_station_affiliates ORDER BY id ASC LIMIT 3');
            
            // $query = "SELECT * FROM station_affiliates ORDER BY id ASC LIMIT 3";
            // $result = @mysql_query($query); // Run the query
            // $result = @mysql_query($result); // Run the query
            		
            		if ($result) {
            			// If the query ran OK, display the result
            			echo '<table width="160" border="0" cellpadding="0" cellspacing="0" bgcolor="666666" class="affiliates">
                                    <tr> 
                                      <td><div align="center"><font color="ffffff" size="1" face="Verdana, Arial, Helvetica, sans-serif"><strong>Boxtorow\'s New Affiliates</strong></font></div></td></tr>';
            						  
            						  // Fetch records and display results
            						  // while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
            						  while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
            							echo '<tr><td class="affiliates">';
            							echo $row['station_name'];
            							echo ' ';
            							echo $row['city'];
            						}
            						echo '</td></tr></table>';
            						
            						mysql_free_result($result); // Free resources;
            						
            			} else {
            				// Public message
            				echo '<p class="error">Not available right now...</p>';
            				// Debugging message
            				// echo '<p>' . mysql_error() . '<br /><br />Query: ' . $query . '</p>';
            				echo '<p>' . mysql_error() . '<br /><br />Query: ' . $query . '</p>';
            			}
            		
            		mysql_close(); // Close DB connection
            }
            


            Yes, a fairly simple and basic call that I'm obviously over-complicating. I still have a lot to learn...
              • 9207 ☆ A M B ☆
              • 2,475 Posts
              Re your code in general: it's best practice to not mix your logic and your formatting. In simple terms, avoid mixing HTML and PHP. Better practice is to keep the PHP logic all nice and clean, and then reference MODX Chunks to format the output. Also, avoid putting functions in your Snippets: it gets messy and the variable scope gets confusing (e.g. your extract() method there may end up with the variables in a scope too small).

              If you have code that you want to reuse beyond its use in a Snippet, then it's best to put that code into a PHP class and your MODX Snippet would be a few lines written to include the class and access that particular function.

              Check out http://rtfm.modx.com/display/revolution20/Snippets and http://rtfm.modx.com/display/revolution20/How+to+Write+a+Good+Snippet for a couple general pointers, including how to read input using getOption and how to log errors.

              Check out http://rtfm.modx.com/display/xPDO20/xPDO.query for an example of how to do a simple query using XPDO.

              Hope that helps. [ed. note: Everettg_99 last edited this post 13 years, 3 months ago.]
              • discuss.answer
                • 42602
                • 81 Posts
                Quote from: opengeek at Jul 05, 2013, 09:19 AM
                Actually, $modx->query and $modx->prepare() are the proper methods to use. Accessing the pdo object directly is not recommended in xPDO. Besides, by using the modX equivalent wrapper methods for PDO, you get on-demand connections. In order to access $modx->pdo, you must already have a connection.

                Forgot these.

                zyruscampbell, code looks fine. Now just remove the mysql_ prefixed methods and it should run nicely.
                  • 33675
                  • 4 Posts
                  I appreciate all the help. Turned out to be as simple as what dunnock commented. I'm still fairly new to MySQL and an absolute noob to PDO. So, I've got a lot of learning to do. But I know where to come for my MODx questions, though. Y'all were great.

                  Thanks!
                    • 33675
                    • 4 Posts
                    Will really come in handy when I try to MySQL-ify THESE pages:
                    http://boxtorow.com/scoreboards/2012_wk3.php

                    A LOT of normalization and table joining will be going on here, I think. But would be a great hands-on project for me to dive in on.

                    Oh well... til next time. Thanks again!
                      • 10525
                      • 247 Posts
                      Quote from: opengeek at Jul 05, 2013, 02:19 PM
                      Actually, $modx->query and $modx->prepare() are the proper methods to use. Accessing the pdo object directly is not recommended in xPDO. Besides, by using the modX equivalent wrapper methods for PDO, you get on-demand connections. In order to access $modx->pdo, you must already have a connection.

                      Can anyone direct me to the best documentation for the use of these functions ($modx->query() and $modx->prepare())? I am using custom db tables added to my modx db. I don't want to start creating objects for these because I am changing tables and code as I build and test. I just want the simplest ways to execute, test and experiment with mysql queries; but the documentation seems to require delving into a whole new world of xPDO objects simply to query tables..

                      I have already successfully used:
                      $sql = "SELECT column FROM table WHERE column = $string";
                      $results = $modx->query($sql);
                      while($row = $results->fetch(PDO::FETCH_ASSOC);
                        //do stuff with $row['column '];
                      }

                      However, when I come to query for a single value, or simply to test for a returned value before trying to use it, or to get a result row count, there doesn't seem to be any documentation out there. I was happy testing with straight php-mysql functions, but now I spend inordinate amounts of time trying to find out how to do simple things simply in MODx...

                      Any offers?