Jason
Jason

Reputation: 11363

Incorporating OOP in existing PHP

I'm trying to incorporate the OOP principles with a web app I'm developing.

Given a class ImageData defined as

class ImageData {
  private $count;
  private $dirArray;

  public function __construct() {
    $count = 0;    
    $dir = "panos/thumbs";
    $dirCon = opendir($dir);

    while ($name = readdir($dirCon)){
      if (strtolower(substr($name, -3)) == "jpg"){
        $dirArray[]= $name;
      }
    }

    sort($dirArray);
    $count= count($dirArray);

    closedir($dirCon);
  }

  public function getCount(){
    return $this->count;
  }

  public function getArray(){
    return $this->dirArray;
  }

}

I want to use the information here to use in rendering a web page. Within the specified div element, I have

$imageData = new ImageData();
$count = $imageData->getCount();
$data = $imageData->getArray();

However, $count and $data are not instanciated locally, and the information contained is not available for usage in the render code. I've stepped through the code in xdebug, and the constructor assigns the expected values to $count and $data. In Java and C, its not required for variables to be instanciated at declaration. Is this true for PHP?

Upvotes: 0

Views: 97

Answers (2)

tereško
tereško

Reputation: 58444

DISCLAIMER: since question obviously has been already answered, this is a long form comment on provided code.

When writing classes, you should try to avoid computation in the constructor. It makes for hard to debug code.

I would actually structure the code like this:

class ImageData {
    protected $count = 0;
    protected $dir = null; 
    protected $dirArray = null; 

    public function __construct( $dir = 'panos/thumbs') {
        $this->dir = $dir;   
    }

    public function getCount(){

       if ( is_array($this->dirArray) ){
           $this->initialize();
       }

       return $this->count;
    }

    public function getArray(){

       if ( is_array($this->dirArray) ){
           $this->initialize();
       }

       return $this->dirArray;
    }

    protected function initialize(){

       $this->dirArray = $this->findImages();

       sort($this->dirArray);
       $this->count = count($dirArray);

    }

    protected function findImages( $extensions = array('jpg') ){

       $files = array();
       $dirCon = opendir($this->dir);

       while ($name = readdir($dirCon)){
           $current = strtolower(substr($foo, strrpos($foo, '.')+1));
           if ( in_array( $current, $extensions ) ){
               $files[] = $name;
           }
       }

       closedir($dirCon);
       return $files
    }

}

First of all, i would recommend to use protected instead of private, if you do not now that you actually need them private. Because the private members of class are not "visible", when you extend the class.

The other thing would be to move the initialization of object to a position, when it is actually required. With minor modifications, this class would enable you to search folder repeatedly, or even search in different folders altogether.

If you want to learn how to utilize OOP in context of PHP, start by reading http://php.net/manual/en/language.oop5.php . And you might find PHP Object-Oriented Solutions book to be a big help.

Upvotes: 1

nebulousGirl
nebulousGirl

Reputation: 1364

In your contructor, you have to use $this->count instead of $count, same for $dirArray.

PS: You can in PHP classes only declare your variables as you did.

Upvotes: 4

Related Questions