Link to home
Start Free TrialLog in
Avatar of Colin Brazier
Colin BrazierFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Process records php/database

Hi experts,

I have decided to refactor my site so I could be the source of 000's of points over the next few weeks!   In particular I am trying to make it more object orientated.

This first question is quite fundamental...it's important I understand this before continuing.

I have attached my classes file.  My calling code is below.

<?php  
include("fobg.inc");
include_once("classes/fobg_database.php");

$db = new Fobg_database( $host, $user, $password, $database );

$sql = "SELECT importance, item FROM headlines_new WHERE trim(item) <> '' ORDER BY importance";
$sql_query = $db->select($sql);
$counter = 0;

while ($row = $db->nextArray($sql_query))  // Wrong class?!
{
      $counter++;
      extract($row);
        ...
        ...
}      
?>

My question is, what is the correct way of accessing and processing records...how do I access the nextArray function from the calling code?

Thanks for reading,

Col fobg-database.php
Avatar of Marco Gasi
Marco Gasi
Flag of Spain image

nextArray function belongs to another class, MysqlResult class so you have to instantiate this class also passing to it the result of your query:
<?php  
include("fobg.inc");
include_once("classes/fobg_database.php");

$db = new Fobg_database( $host, $user, $password, $database );

$sql = "SELECT importance, item FROM headlines_new WHERE trim(item) <> '' ORDER BY importance";
$sql_query = $db->select($sql);
$counter = 0;
$results = new MysqlResult($sql_query);

while ($row = $results->nextArray()  // Wrong class?!
{
      $counter++;
      extract($row);
        ...
        ...
}      
?>

Open in new window


Now I have no time to test this code and I don't know if it works, so try it. But I think you should have only one class to do query and to manage results. Maybe you can look for an  existing class...

Cheers
Avatar of Colin Brazier

ASKER

Thanks.  I see what you mean, but I am now getting

mysql_fetch_array() expects parameter 1 to be resource, object given.

Do I need to pass something to mysql_fetch_array() ?

Col
Do I need to pass something to mysql_fetch_array() ?
Yes.  You need to pass the MySQL results resource that is returned by successful execution of mysql_query()
ASKER CERTIFIED SOLUTION
Avatar of Marco Gasi
Marco Gasi
Flag of Spain image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Most of what should be said has been said.  I suggest you read   http://www.w3schools.com/php/php_mysql_intro.asp
Thanks everyone.  I actually meant to say do I need to pass something to $results->nextArray() not mysql_fetch_array() ...sorry!

OK, I am actually using http://www.amazon.com/PHP-Action-Objects-Design-Agility/dp/1932394753/ref=pd_sim_b2  but will have a look at your link.

I am not expecting EE to provide me with the knowledge to rework the whole site.  That would indeed take some time (but I don't class it in the miracle category!).  I am just using EE to help me get the basics right.  I am using my working, procedural, legacy website as a tool to being a more efficient developer for future enhancements to this site and other projects.

  Col
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
OK, miracle it would be!

marqusG I agree 100% with your suggestions.  Ray too; perhaps I am trying to leap too far in one bound.  

marqus, the code you suggest

$sql = "SELECT importance, item FROM headlines_new WHERE trim(item) <> '' ORDER BY importance";
$result = mysql_query($sql);
while ($row = mysql_fetch_array($result)){
}

is actually what I started out with, so I guess this proves both your points!

Cheers,

   Col
Thanks for your advice and time.

Col
I agree with Ray.  Start with something simple.

If this is your personal website, perhaps breaking it isn't so bad.  However, I agree with Ray that you start with something new.  Once you have that working, then decide what you want to do with the rest of the site.
Yup - agreed.
Looking better at your class code, I would effectively like to know why it is not working. It seems there is something not working in the execute method. In the code you've posted throwOnMysqlError() seems to grab only connection errors. I suggest to modify your code this way:
function select($sql) {
  $selectResult = @mysql_query($sql, $this->dbLink) or die(mysql_error();  // @ suppresses legacy PHP errors.
  $this->throwOnMysqlError();
  return new MysqlResult($selectResult);
}

Open in new window

so we can see if any error occur there, since the error you get seems to say that any result resource is passed to it.

Cheers
Ooops, I had not seen you had award points yet! You're welcome, but try what I said... I'm curious ;-)
marqusG,

I am getting the same error with that code....

Warning: mysql_fetch_array() expects parameter 1 to be resource, object given in E:\xampp\htdocs2\classes\fobg_database.php on line 47
The code should check to make sure $result is valid.  While failing to do that could throw a warning, I don't think it would throw the cited warning.  (Still, you should fix that.)

As for the warning, I suggest you post code.
Relevant code below...


include("fobgdb.inc");
include_once("classes/fobg_database.php");
$db = new Fobg_database( $host, $user, $password, $database );

$sql = "SELECT importance, item FROM headlines_new WHERE trim(item) <> '' ORDER BY importance";
$sql_query = $db->select($sql);
$counter = 0;
$results = new MysqlResult($sql_query);

while ($row = $results->nextArray())
{
      $counter++;
      extract($row);
      $headline[$counter] = $item;
}      

====================================================

<?php
class Fobg_database {
      
      private $dbLink; # needed to keep the database connection open
                  
      # Database connection variables
    function __construct($host, $user, $password, $database)
    {
            # connect to the MySQL server and select the database
            $this->dbLink = mysql_connect($host, $user, $password);
            mysql_select_db($database, $this->dbLink);
            $this->throwOnMysqlError();
    }
      
      private function throwOnMysqlError() {
            if ($error = mysql_error($this->dbLink)) {
                  throw new Exception($error);
            }
      }
            
      function select($sql) {
            $selectResult = @mysql_query($sql, $this->dbLink) or die(mysql_error());  // @ suppresses legacy PHP errors.
              $this->throwOnMysqlError();
              return new MysqlResult($selectResult);
      }
      
}
      
class MysqlResult {
      private $result;  //why is this needed?
      
      function __construct($selectResult) {
            $this->result = $selectResult;
      }
      
      function nextArray() {
            return mysql_fetch_array($this->result);
      }
}
?>
Now I see how a false result could return the object error.

I think you really should make sure that $selectResult is a valid resource (!= false) before using it.

I'd make several changes, if it was me, but at a minimum I think you should check to make sure that $this->result isn't false before using it.
Like this?

function select($sql) {
            $selectResult = @mysql_query($sql, $this->dbLink) or die(mysql_error());  
              $this->throwOnMysqlError();
            if ($selectResult != false) {
                  return new MysqlResult($selectResult);
            }
      }
Please, revert to your original code and try this to call nextArray()

<?php  
include("fobg.inc");
include_once("classes/fobg_database.php");

$db = new Fobg_database( $host, $user, $password, $database );

$sql = "SELECT importance, item FROM headlines_new WHERE trim(item) <> '' ORDER BY importance";
$sql_query = $db->select($sql);
$counter = 0;

while ($row = $sql_query->nextArray())  // Wrong class?!
{
      $counter++;
      extract($row);
        ...
        ...
}      
?>

In fact, $sql_query is an object derived from MySqlResult class. In your original call you passed an object instance to nextArray function and nextArray was treated as a method of $db not of $sql_query

So, summarizing:
- you instantate a new object of type Fobg_database: $db
- you call $db->select method to execute a select query assigning result to variable $sql_query
- this variable is a new object of type MySqlResult
- then we have to use this object to call nextArray function without passing nothing to it since it internally uses the $selectResult passed in the constructor by the select method of the $db object

Hope to have been clear.

Let me know if it works ;-)
Yes but you don't need the != false as that is implied.  However, how about trying marqusG's suggestion first?
Works!!!

I can only presume I have overcomplicated it!
Have you tried my code or it works for some other reason?
No your latest code was spot on.  Ta!
If this is the case, look at explanations I provided and feel free to ask if something is not clear.

Cheers
marqusG,

You made everything very clear.  I get the impression it's not the recommended way though. So do you still think I should revert to:

<Second: usually code to scan a query result set is

$sql = "SELECT importance, item FROM headlines_new WHERE trim(item) <> '' ORDER BY importance";
$result = mysql_query($sql);
while ($row = mysql_fetch_array($result)){
}   >
No. That is the procedural way: obviously it works but it has nothing to do with classes and oop.

I'm talking about my post ID:36969387: if you didn't read it, take a look: it is possible there you find the solution to your specific problem (remaining other considerations made valid)

Cheers
Yes, I am too.  That code while ($row = $sql_query->nextArray())    donk bets...is fine.  I'll stick with that then.
Yes, I am too.  That code while ($row = $sql_query->nextArray())    ...is fine.  I'll stick with that then.