Objects and Arrays

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • TKirahvi

    Objects and Arrays

    Why can't I create Objects in an Array within for/while loop?

    If I have:

    Code:

    $galleries = array();

    while( $db->next_record( ) )
    {
    $foo = $db->f('id');
    $galleries[] = new Gallery($foo);
    }


    Database query returns two id's and galleries array should then
    contain two Gallery Objects but it contains only the first one.

    If I do it like this, it works fine:

    Code:

    $galleries[] = new Gallery(1);
    $galleries[] = new Gallery(2);


    I have PHP 5.1.6

    Thanks in advance

  • Schraalhans Keukenmeester

    #2
    Re: Objects and Arrays

    TKirahvi wrote:
    Why can't I create Objects in an Array within for/while loop?
    >
    If I have:
    >
    Code:
    >
    $galleries = array();
    >
    while( $db->next_record( ) )
    {
    $foo = $db->f('id');
    $galleries[] = new Gallery($foo);
    }
    >
    >
    Database query returns two id's and galleries array should then
    contain two Gallery Objects but it contains only the first one.
    >
    If I do it like this, it works fine:
    >
    Code:
    >
    $galleries[] = new Gallery(1);
    $galleries[] = new Gallery(2);
    >
    >
    I have PHP 5.1.6
    >
    Thanks in advance
    >
    What values does $db->f('id') return? Are there really two records? Is
    $db's class doing what it's supposed to?

    The problem does not lie in the assignment to $galleries[], that's for
    sure. So the problem is elsewhere in your code, or the concept behind
    it. Post more details, and test your snippet by echoing intermediate
    results to screen. Perhaps there's a good clue.

    Sh.

    Comment

    • TKirahvi

      #3
      Re: Objects and Arrays

      What values does $db->f('id') return? Are there really two records? Is
      $db's class doing what it's supposed to?
      >
      The problem does not lie in the assignment to $galleries[], that's for
      sure. So the problem is elsewhere in your code, or the concept behind
      it. Post more details, and test your snippet by echoing intermediate
      results to screen. Perhaps there's a good clue.
      >
      If I echo($db-f('id')); within while loop, it echoes correct id
      numbers (in this case 1 and 2), as so:

      while( $db->next_record( ) )
      {
      $foo = $db->f('id');
      echo($foo);
      }

      output: 1 2

      But if I create Gallery Objects within the loop, I guess only first
      one is created properly:

      while( $db->next_record( ) )
      {
      $foo = $db->f('id');
      gallery = new Gallery($foo);
      echo($gallery->id);
      }

      output: 1

      So it seems Arrays has nothing to do with this. I wonder if Gallery
      Object is missing something crucial, I'm not that familiar with PHP's
      Objects. My Gallery Object is:

      class Gallery
      {
      var $id;
      var $name;
      var $description;
      var $owner;
      var $authority;
      var $date;

      function __construct($id )
      {
      global $db;

      $select = 'SELECT * FROM gallery WHERE id = '.$id;
      $result = $db->query( $select );

      if ( !$result) {
      echo( 'Query failed');
      }
      else
      {
      $db->next_record( );
      $this->id = $db->f("id");
      $this->name = $db->f("name");
      $this->description = $db->f("description ");
      $this->owner = $db->f("owner");
      $this->authority = $db->f("authority") ;
      $this->date = $db->f("date");
      }
      }

      function __get($v)
      {
      return $this->$v;
      }
      }

      Comment

      • Jerry Stuckle

        #4
        Re: Objects and Arrays

        TKirahvi wrote:
        >What values does $db->f('id') return? Are there really two records? Is
        >$db's class doing what it's supposed to?
        >>
        >The problem does not lie in the assignment to $galleries[], that's for
        >sure. So the problem is elsewhere in your code, or the concept behind
        >it. Post more details, and test your snippet by echoing intermediate
        >results to screen. Perhaps there's a good clue.
        >>
        >
        If I echo($db-f('id')); within while loop, it echoes correct id
        numbers (in this case 1 and 2), as so:
        >
        while( $db->next_record( ) )
        {
        $foo = $db->f('id');
        echo($foo);
        }
        >
        output: 1 2
        >
        But if I create Gallery Objects within the loop, I guess only first
        one is created properly:
        >
        while( $db->next_record( ) )
        {
        $foo = $db->f('id');
        gallery = new Gallery($foo);
        echo($gallery->id);
        }
        >
        output: 1
        >
        So it seems Arrays has nothing to do with this. I wonder if Gallery
        Object is missing something crucial, I'm not that familiar with PHP's
        Objects. My Gallery Object is:
        >
        class Gallery
        {
        var $id;
        var $name;
        var $description;
        var $owner;
        var $authority;
        var $date;
        >
        function __construct($id )
        {
        global $db;
        >
        $select = 'SELECT * FROM gallery WHERE id = '.$id;
        $result = $db->query( $select );
        >
        if ( !$result) {
        echo( 'Query failed');
        }
        else
        {
        $db->next_record( );
        $this->id = $db->f("id");
        $this->name = $db->f("name");
        $this->description = $db->f("description ");
        $this->owner = $db->f("owner");
        $this->authority = $db->f("authority") ;
        $this->date = $db->f("date");
        }
        }
        >
        function __get($v)
        {
        return $this->$v;
        }
        }
        >
        Your problem is you're reusing $db in your class. When you issue:

        $result = $db->query( $select );

        You have wiped out the recordset you're using in:

        while( $db->next_record( ) )

        If you're going to make another request, you need to use another object.

        A real good reason why you shouldn't use globals.

        --
        =============== ===
        Remove the "x" from my email address
        Jerry Stuckle
        JDS Computer Training Corp.
        jstucklex@attgl obal.net
        =============== ===

        Comment

        • Schraalhans Keukenmeester

          #5
          Re: Objects and Arrays

          TKirahvi wrote:
          >What values does $db->f('id') return? Are there really two records? Is
          >$db's class doing what it's supposed to?
          >>
          >The problem does not lie in the assignment to $galleries[], that's for
          >sure. So the problem is elsewhere in your code, or the concept behind
          >it. Post more details, and test your snippet by echoing intermediate
          >results to screen. Perhaps there's a good clue.
          >>
          >
          If I echo($db-f('id')); within while loop, it echoes correct id
          numbers (in this case 1 and 2), as so:
          >
          while( $db->next_record( ) )
          {
          $foo = $db->f('id');
          echo($foo);
          }
          >
          output: 1 2
          >
          But if I create Gallery Objects within the loop, I guess only first
          one is created properly:
          >
          while( $db->next_record( ) )
          {
          $foo = $db->f('id');
          gallery = new Gallery($foo);
          echo($gallery->id);
          }
          >
          output: 1
          >
          So it seems Arrays has nothing to do with this. I wonder if Gallery
          Object is missing something crucial, I'm not that familiar with PHP's
          Objects. My Gallery Object is:
          >
          class Gallery
          {
          var $id;
          var $name;
          var $description;
          var $owner;
          var $authority;
          var $date;
          >
          function __construct($id )
          {
          global $db;
          >
          $select = 'SELECT * FROM gallery WHERE id = '.$id;
          $result = $db->query( $select );
          >
          if ( !$result) {
          echo( 'Query failed');
          }
          else
          {
          $db->next_record( );
          $this->id = $db->f("id");
          $this->name = $db->f("name");
          $this->description = $db->f("description ");
          $this->owner = $db->f("owner");
          $this->authority = $db->f("authority") ;
          $this->date = $db->f("date");
          }
          }
          >
          function __get($v)
          {
          return $this->$v;
          }
          }
          >
          I'd think the problem lies in the fact your Gallery constructor itself
          interacts with the class $db is an instance of. First of all using a
          global var in a class like you did here doesn't seem a thought-through
          OOP construction. I'd avoid using globals in a class like the plague
          personally.

          Inside the constructor you make a call to $db->next_record( ) again, so
          the loop in your calling script makes a THIRD call, not the second.
          This undoubtedly causes your problem.

          This example definitely doesn't come across as a good design, so you may
          help yourself by redesigning the Gallery class and do away with
          accessing global objects' methods inside it.

          HTH, Sh.

          Comment

          • Simon Stienen

            #6
            Re: Objects and Arrays

            On 2007-04-02 16-29-44, Jerry Stuckle wrote:
            Your problem is you're reusing $db in your class. When you issue:
            >
            $result = $db->query( $select );
            >
            You have wiped out the recordset you're using in:
            >
            while( $db->next_record( ) )
            >
            If you're going to make another request, you need to use another object.
            >
            A real good reason why you shouldn't use globals.
            Actually, it's not the global variable that causes the problem, but the bad
            design of the DB class. The problem would be the same if he passed the DB
            object as a parameter to the ctor - however, if the DB class would be
            capable of handling concurrent queries (most likely by letting ::query()
            return a result object), the problem wouldn't occur even with a global
            variable.

            So - yes, the global variable is a desease... but not the one the symptom
            is pointing to. :)


            HTH

            Comment

            • Jerry Stuckle

              #7
              Re: Objects and Arrays

              Simon Stienen wrote:
              On 2007-04-02 16-29-44, Jerry Stuckle wrote:
              >Your problem is you're reusing $db in your class. When you issue:
              >>
              >$result = $db->query( $select );
              >>
              >You have wiped out the recordset you're using in:
              >>
              >while( $db->next_record( ) )
              >>
              >If you're going to make another request, you need to use another object.
              >>
              >A real good reason why you shouldn't use globals.
              >
              Actually, it's not the global variable that causes the problem, but the bad
              design of the DB class. The problem would be the same if he passed the DB
              object as a parameter to the ctor - however, if the DB class would be
              capable of handling concurrent queries (most likely by letting ::query()
              return a result object), the problem wouldn't occur even with a global
              variable.
              >
              Not at all a bad design. Any class will do the same thing. It handles
              a single query. If you make another query, that will overwrite the
              original query. If you want two concurrent queries, you use two db objects.

              A variable will do the same thing.


              The reason for not using globals is mainly for clarity. It's much more
              obvious what's happening when you pass a variable to a function.

              So - yes, the global variable is a desease... but not the one the symptom
              is pointing to. :)
              >
              >
              No, it's not this symptom. But he would have been more likely to see
              his problem if he would have passed it as a parameter and not used a global.
              HTH


              --
              =============== ===
              Remove the "x" from my email address
              Jerry Stuckle
              JDS Computer Training Corp.
              jstucklex@attgl obal.net
              =============== ===

              Comment

              • Simon Stienen

                #8
                Re: Objects and Arrays

                On 2007-04-03 04-52-47, Jerry Stuckle wrote:
                Not at all a bad design. Any class will do the same thing. It handles
                a single query. If you make another query, that will overwrite the
                original query. If you want two concurrent queries, you use two db objects.
                One query per _DATABASE_? Sorry, but I think this is a somewhat limited
                approach.

                Comment

                • Jerry Stuckle

                  #9
                  Re: Objects and Arrays

                  Simon Stienen wrote:
                  On 2007-04-03 04-52-47, Jerry Stuckle wrote:
                  >Not at all a bad design. Any class will do the same thing. It handles
                  >a single query. If you make another query, that will overwrite the
                  >original query. If you want two concurrent queries, you use two db objects.
                  >
                  One query per _DATABASE_? Sorry, but I think this is a somewhat limited
                  approach.
                  No, the DB object represents a QUERY. You can have one QUERY open at a
                  time. This is pretty standard for objects - each instantiation handles
                  a specific object.

                  In this case the DB object represents a query (and its results), so you
                  can have one query open at a time per DB object. The same is pretty
                  true in all OO languages. I've used similar in C++, Java and even VBScript.

                  It's all in understanding the purpose of the object.


                  --
                  =============== ===
                  Remove the "x" from my email address
                  Jerry Stuckle
                  JDS Computer Training Corp.
                  jstucklex@attgl obal.net
                  =============== ===

                  Comment

                  • Jerry Stuckle

                    #10
                    Re: Objects and Arrays

                    Simon Stienen wrote:
                    On 2007-04-03 04-52-47, Jerry Stuckle wrote:
                    >Not at all a bad design. Any class will do the same thing. It handles
                    >a single query. If you make another query, that will overwrite the
                    >original query. If you want two concurrent queries, you use two db objects.
                    >
                    One query per _DATABASE_? Sorry, but I think this is a somewhat limited
                    approach.
                    And don't confuse a DB object with the database itself. They are not
                    the same thing.

                    --
                    =============== ===
                    Remove the "x" from my email address
                    Jerry Stuckle
                    JDS Computer Training Corp.
                    jstucklex@attgl obal.net
                    =============== ===

                    Comment

                    • Simon Stienen

                      #11
                      Re: Objects and Arrays

                      On 2007-04-03 05-51-52, Jerry Stuckle wrote:
                      No, the DB object represents a QUERY.
                      a) Why isn't the query represented by a QUERY object?
                      b) It's definitely NOT true that an object represents something and then
                      something else (even if of the same type). The OOP approach would be to
                      have a QUERY object represent a query and build a new query object for a
                      new query. Additionally, it's bollocks to use a single query object
                      throughout the whole application for several queries. Especially if this
                      query object is called DB.

                      Next: A result is not a query but the result of a single invocation of this
                      query, therefore regardless how you call your query object, it's still
                      stupid to store the result in the same object. It should be returned as a
                      new instance of a result type - just as I mentioned several posts before.

                      Third: Taking C++ as an example: MySQL++ is doing exactly that. There is
                      mysqlpp::Query (not mysql::DB! - to all the onlookers not familiar with
                      C++: In C++ the scope operator :: is also used to seperate namespaces from
                      type names within them - just take the whole "mysqlpp::* " as typename to
                      use with new) which has a few methods to execute the query which will then
                      return a mysqlpp::Result instance. Just as I said. It's all in
                      understanding the purpose of the object.

                      Comment

                      • Jerry Stuckle

                        #12
                        Re: Objects and Arrays

                        Simon Stienen wrote:
                        On 2007-04-03 05-51-52, Jerry Stuckle wrote:
                        >No, the DB object represents a QUERY.
                        >
                        a) Why isn't the query represented by a QUERY object?
                        Because it's called a db object. Maybe my description was confusing.
                        The query need not be a SELECT. It could be an INSERT, CREATE TABLE or
                        anything else.
                        b) It's definitely NOT true that an object represents something and then
                        something else (even if of the same type). The OOP approach would be to
                        have a QUERY object represent a query and build a new query object for a
                        new query. Additionally, it's bollocks to use a single query object
                        throughout the whole application for several queries. Especially if this
                        query object is called DB.
                        >
                        I didn't say that. I said that an object represents one thing at a
                        time. Your OOP approach is one way. This is another - and is just as
                        valid.
                        Next: A result is not a query but the result of a single invocation of this
                        query, therefore regardless how you call your query object, it's still
                        stupid to store the result in the same object. It should be returned as a
                        new instance of a result type - just as I mentioned several posts before.
                        >
                        In you opinion. Millions of developers disagree with you. It's just a
                        different way of doing things.
                        Third: Taking C++ as an example: MySQL++ is doing exactly that. There is
                        mysqlpp::Query (not mysql::DB! - to all the onlookers not familiar with
                        C++: In C++ the scope operator :: is also used to seperate namespaces from
                        type names within them - just take the whole "mysqlpp::* " as typename to
                        use with new) which has a few methods to execute the query which will then
                        return a mysqlpp::Result instance. Just as I said. It's all in
                        understanding the purpose of the object.
                        Yep, and there are also C++ classes which work exactly the way the db
                        class in this program works. Different ways of doing things.

                        Just because it doesn't work the way you want it to work doesn't mean
                        it's wrong. It's a different way of looking at database communications,
                        and is just as valid as the way you're familiar with.

                        --
                        =============== ===
                        Remove the "x" from my email address
                        Jerry Stuckle
                        JDS Computer Training Corp.
                        jstucklex@attgl obal.net
                        =============== ===

                        Comment

                        • Simon Stienen

                          #13
                          Re: Objects and Arrays

                          On 2007-04-03 06-46-03, Jerry Stuckle wrote:
                          >a) Why isn't the query represented by a QUERY object?
                          Because it's called a db object. Maybe my description was confusing.
                          The query need not be a SELECT. It could be an INSERT, CREATE TABLE or
                          anything else.
                          Oh... So queries are always SELECTs and INSERTs etc. are not queries...
                          thanks for teaching me *that*, as this is really something completely new
                          for.

                          And good to know that you automagically know what HIS DB object does and
                          what not.

                          Comment

                          • Toby A Inkster

                            #14
                            Re: Objects and Arrays

                            Jerry Stuckle wrote:
                            Simon Stienen wrote:
                            >On 2007-04-03 04-52-47, Jerry Stuckle wrote:
                            >>
                            >>Not at all a bad design. Any class will do the same thing. It
                            >>handles a single query. If you make another query, that will
                            >>overwrite the original query. If you want two concurrent queries,
                            >>you use two db objects.
                            >>
                            >One query per _DATABASE_? Sorry, but I think this is a somewhat
                            >limited approach.
                            >
                            No, the DB object represents a QUERY. You can have one QUERY open
                            at a time. This is pretty standard for objects - each
                            instantiation handles a specific object.
                            The normal way that database objects seem to operate in PHP is that one
                            database object can handle multiple concurrent queries by returning a
                            "ResultSet" type element for each query, such that the ResultSet can be
                            assigned to a variable and used at a later date, and the main database
                            object can be used for other queries in the meantime.

                            That is, they do not do:

                            $db1->query("SELEC T ...");
                            $db2->query("SELEC T ...");
                            $rows[] = $db1->fetch();
                            $more[] = $db2->fetch();

                            which requires two (usually heavyweight) database objects, but instead do:

                            $resultset1 = $db->query("SELEC T ...");
                            $resultset2 = $db->query("SELEC T ...");
                            $rows[] = $resultset1->fetch();
                            $more[] = $resultset2->fetch();

                            which only requires one database object.

                            Examples of the kind of behaviour Simon's describing include the mysqli
                            extension's "query" method, PDO's "query" method, and PEAR package DB. The
                            same principles, though using a slightly odd syntax can be found in PEAR's
                            MDB package:

                            $resultset1 = $db->query("SELEC T ...");
                            $resultset2 = $db->query("SELEC T ...");
                            $rows[] = $db->fetchInto($res ultset1);
                            $more[] = $db->fetchInto($res ultset2);

                            Again the same principle can be seen in most of the older non-OO database
                            interfaces, though (obviously) using a less object-oriented syntax:

                            $resultset1 = dbx_query($db, "SELECT ...");
                            $resultset2 = dbx_query($db, "SELECT ...");
                            $rows[] = dbx_fetch_row($ resultset1);
                            $more[] = dbx_fetch_row($ resultset2);

                            --
                            Toby A Inkster BSc (Hons) ARCS
                            Contact Me ~ http://tobyinkster.co.uk/contact
                            Geek of ~ HTML/SQL/Perl/PHP/Python*/Apache/Linux

                            * = I'm getting there!

                            Comment

                            • Jerry Stuckle

                              #15
                              Re: Objects and Arrays

                              Simon Stienen wrote:
                              On 2007-04-03 06-46-03, Jerry Stuckle wrote:
                              >>a) Why isn't the query represented by a QUERY object?
                              >Because it's called a db object. Maybe my description was confusing.
                              >The query need not be a SELECT. It could be an INSERT, CREATE TABLE or
                              >anything else.
                              >
                              Oh... So queries are always SELECTs and INSERTs etc. are not queries...
                              thanks for teaching me *that*, as this is really something completely new
                              for.
                              >
                              And good to know that you automagically know what HIS DB object does and
                              what not.
                              It's pretty obvious from the code what his object does. I've used
                              similar code may times before.

                              The difference is you're thinking of it as a db connection with a
                              separate result object. That's a very valid way of doing things.

                              However, his code is a little different (and just as valid). He sees
                              the query as a method of the object. Each way has its advantages and
                              disadvantages.

                              --
                              =============== ===
                              Remove the "x" from my email address
                              Jerry Stuckle
                              JDS Computer Training Corp.
                              jstucklex@attgl obal.net
                              =============== ===

                              Comment

                              Working...