SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    63 Post(s)
    Tagged
    2 Thread(s)

    Cleaner static variable use

    PHP Code:
    $db self::$var1;
    $coll self::$var2;
    $rDb self::$var3;
            
    $m->$db->$coll->find(); 
    As you can see I'm using the variables in the object $m; I first have to re-assign the static variables, as the self::$var can't be used in an object. Any ideas on a cleaner way to get around this?

  2. #2
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,069
    Mentioned
    152 Post(s)
    Tagged
    0 Thread(s)
    Hmmm... I haven't tested this but I thought the following was possible:
    PHP Code:
    $m->{self::$db}->{self::$coll}->find(); 
    Granted, personally, I'd take this as a warning that your use of static may be ill-advised in this scenario and consider why you made them static to begin with.
    Be sure to congratulate Patche on earning July's Member of the Month
    Go ahead and blame me, I still won't lose any sleep over it
    My Blog | My Technical Notes

  3. #3
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    63 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by cpradio View Post
    Hmmm... I haven't tested this but I thought the following was possible:
    PHP Code:
    $m->{self::$db}->{self::$coll}->find(); 
    Granted, personally, I'd take this as a warning that your use of static may be ill-advised in this scenario and consider why you made them static to begin with.
    Well, they are for use within a few functions, but within only this single class, and never to be altered by a child or outside source (EDIT: or even the class itself, they just need defined once and never altered), it just seemed logical to me, minus the fact that I'm redecalring them every time I want to use them in an object such as this.

    This is for use in a MongoDB class, so I'm declaring the db and collection to be used across the class one time, but using it many.

    EDIT: This does work, much cleaner. Thank you.

  4. #4
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    63 Post(s)
    Tagged
    2 Thread(s)
    An altered example of what I'm doing:

    PHP Code:
    class Album {
        private static 
    $AlbumDb 'my_db';
        private static 
    $AlbumColl 'my_coll';
        
        public 
    $mongo;
        
        public function 
    construct() {
            
    $this->mongo = new MongoClient();
        }
        
        public function 
    AddAlbum($AlbumName) {
            try {
                
    $this->mongo->{self::$AlbumDb}->{self::AlbumColl}->insert(array('album_name' => $AlbumName));
            } catch(
    MongoCursorException $e) {
                Throw New 
    Exception($e);
            }
        }
        
        public function 
    DeleteAlbum($AlbumName) {
            try {
                
    $this->mongo->{self::$AlbumDb}->{self::AlbumColl}->remove(array('album_name' => $AlbumName));
            } catch(
    MongoCursorException $e) {
                Throw New 
    Exception($e);
            }
        }


  5. #5
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,036
    Mentioned
    152 Post(s)
    Tagged
    2 Thread(s)
    Why not just set the db once in the constructor and use that throughout?

    PHP Code:
    class MyDB
    {
      private 
    $db;

      public function 
    __construct($db$collection)
      {
        
    $this->db = new MongoCollection();
        
    $this->db->selectDb($db);
        
    $this->db->selectCollection($collection);
      }

      public function 
    doSomething()
      {
        
    // use $this->db to query
      
    }

    Rémon - Hosting Advisor

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy

  6. #6
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    63 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    Why not just set the db once in the constructor and use that throughout?

    PHP Code:
    class MyDB
    {
      private 
    $db;

      public function 
    __construct($db$collection)
      {
        
    $this->db = new MongoCollection();
        
    $this->db->selectDb($db);
        
    $this->db->selectCollection($collection);
      }

      public function 
    doSomething()
      {
        
    // use $this->db to query
      
    }

    You know this is one of those moments you want to slap yourself, just a little, as I used to write it like this.

    Though I would only separate the mongo collection and the connection as the original connection does get re-used for other collections. Thanks for the quick reality check

  7. #7
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,036
    Mentioned
    152 Post(s)
    Tagged
    2 Thread(s)
    Also, I would create a sort of superclass for basic functionality so you're repeating yourself over and over again with different names and parameters.

    PHP Code:
    abstract class Model
    {
      private 
    $dbName;
      private 
    $collectionName;

      public function 
    __construct($dbName$collectionName)
      {
          
    $this->db = new MongoClient();
          
    $this->db->selectDb($dbName);
          
    $this->db->selectCollection($collectionName);
      }

      public function 
    insert($data)
      {
        try {
          
    $this->db->insert($data);
        } catch(
    MongoCursorException $e) {
           throw new 
    Exception($e); // why?
        
    }
      }

      public function 
    delete($data)
      {
        try {
          
    $this->db->delete($data);
        } catch(
    MongoCursorException $e) {
           throw new 
    Exception($e); // why?
        
    }
      }
    }

    class 
    Album extends Model
    {
      public function 
    __construct()
      {
        
    parent::construct('my_db''my_collection');
      }

      
    // if you want you can add functions like
      // this to hide implementation details
      // like the 'album_name' key. Or you
      // can just call ->insert and ->delete
      // from "outside"
      
    public function addAlbum($albumName)
      {
        
    $this->insert(array('album_name' => $albumName));
      }

      public function 
    deleteAlbum($albumName)
      {
        
    $this->delete(array('album_name' => $albumName));
      }

    That way you've also moved all the try {} catch {} stuff out of the way to the superclass and you can concentrate on real business logic in the implementing classes.
    Rémon - Hosting Advisor

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy

  8. #8
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    63 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    Also, I would create a sort of superclass for basic functionality so you're repeating yourself over and over again with different names and parameters.

    PHP Code:
    abstract class Model
    {
      private 
    $dbName;
      private 
    $collectionName;

      public function 
    __construct($dbName$collectionName)
      {
          
    $this->db = new MongoClient();
          
    $this->db->selectDb($dbName);
          
    $this->db->selectCollection($collectionName);
      }

      public function 
    insert($data)
      {
        try {
          
    $this->db->insert($data);
        } catch(
    MongoCursorException $e) {
           throw new 
    Exception($e); // why?
        
    }
      }

      public function 
    delete($data)
      {
        try {
          
    $this->db->delete($data);
        } catch(
    MongoCursorException $e) {
           throw new 
    Exception($e); // why?
        
    }
      }
    }

    class 
    Album extends Model
    {
      public function 
    __construct()
      {
        
    parent::construct('my_db''my_collection');
      }

      
    // if you want you can add functions like
      // this to hide implementation details
      // like the 'album_name' key. Or you
      // can just call ->insert and ->delete
      // from "outside"
      
    public function addAlbum($albumName)
      {
        
    $this->insert(array('album_name' => $albumName));
      }

      public function 
    deleteAlbum($albumName)
      {
        
    $this->delete(array('album_name' => $albumName));
      }

    That way you've also moved all the try {} catch {} stuff out of the way to the superclass and you can concentrate on real business logic in the implementing classes.
    Well perhaps I dumbed my example down too far, and too much into a web format. Most of my functions are very complex, usually 100-200 lines of code, and creating a generic insert, delete, etc doesn't actually contribute anything unless I plan to write in retries.

  9. #9
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,069
    Mentioned
    152 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    Why not just set the db once in the constructor and use that throughout?

    PHP Code:
    class MyDB
    {
      private 
    $db;

      public function 
    __construct($db$collection)
      {
        
    $this->db = new MongoCollection();
        
    $this->db->selectDb($db);
        
    $this->db->selectCollection($collection);
      }

      public function 
    doSomething()
      {
        
    // use $this->db to query
      
    }

    Quote Originally Posted by ScallioXTX View Post
    Also, I would create a sort of superclass for basic functionality so you're repeating yourself over and over again with different names and parameters.

    PHP Code:
    abstract class Model
    {
      private 
    $dbName;
      private 
    $collectionName;

      public function 
    __construct($dbName$collectionName)
      {
          
    $this->db = new MongoClient();
          
    $this->db->selectDb($dbName);
          
    $this->db->selectCollection($collectionName);
      }

      public function 
    insert($data)
      {
        try {
          
    $this->db->insert($data);
        } catch(
    MongoCursorException $e) {
           throw new 
    Exception($e); // why?
        
    }
      }

      public function 
    delete($data)
      {
        try {
          
    $this->db->delete($data);
        } catch(
    MongoCursorException $e) {
           throw new 
    Exception($e); // why?
        
    }
      }
    }

    class 
    Album extends Model
    {
      public function 
    __construct()
      {
        
    parent::construct('my_db''my_collection');
      }

      
    // if you want you can add functions like
      // this to hide implementation details
      // like the 'album_name' key. Or you
      // can just call ->insert and ->delete
      // from "outside"
      
    public function addAlbum($albumName)
      {
        
    $this->insert(array('album_name' => $albumName));
      }

      public function 
    deleteAlbum($albumName)
      {
        
    $this->delete(array('album_name' => $albumName));
      }

    That way you've also moved all the try {} catch {} stuff out of the way to the superclass and you can concentrate on real business logic in the implementing classes.
    Just wanted to point out, this is what I meant by "this may be a warning of an ill-advised scenario and to question why you are doing it", I just didn't have the time to think/write out a better approach (plus I didn't have your code at hand ) Thank you @ScallioXTX ; for having the time to do that.

    I believe the approach you wrote will be far easier to manage. I also like the idea of pushing generic insert/delete/update syntax to the super-class, let it worry about how the database should be interacted with, and allow your other classes to just push data to it. The less data access you can do within the business layer the better And when you find yourself in a spot where you need to do more, extend your super-class to handle that unique scenario and call it from your business layer.
    Be sure to congratulate Patche on earning July's Member of the Month
    Go ahead and blame me, I still won't lose any sleep over it
    My Blog | My Technical Notes

  10. #10
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    63 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by cpradio View Post
    Just wanted to point out, this is what I meant by "this may be a warning of an ill-advised scenario and to question why you are doing it", I just didn't have the time to think/write out a better approach (plus I didn't have your code at hand ) Thank you @ScallioXTX ; for having the time to do that.

    I believe the approach you wrote will be far easier to manage. I also like the idea of pushing generic insert/delete/update syntax to the super-class, let it worry about how the database should be interacted with, and allow your other classes to just push data to it. The less data access you can do within the business layer the better And when you find yourself in a spot where you need to do more, extend your super-class to handle that unique scenario and call it from your business layer.
    Actually I believe the original reason was that my shop is trying to adopt some standards, and I believe we were trying to get our config files up to the top of classes for quick editing. I suppose the constructor is close enough.

    Thinking on this further, this might not be a bad idea to create a superclass. I'm usually running very large batch files, and having some generic error handling such as a retry that I'm usually writing out anyway would be beneficial.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •