简体   繁体   English

Php:学习OOP,静态方法与常规方法

[英]Php: Learning OOP, Static vs normal method

This is my first post in Stack Overflow so bear with me if I don't conform to any of the rules. 这是我在Stack Overflow中的第一篇文章,所以如果我不遵守任何规则,请多多包涵。 I have been scripting in php for a while now but have never actually used any of its OOP side. 我已经使用php编写脚本已有一段时间了,但是从未真正使用过它的OOP方面。 I have been doing a training course on-line (not sure if i'm aloud to state which one because of copyright ?) 我一直在进行在线培训课程(不确定是否因为版权而大声地说出哪一个?)

Either way during the course the programmer made a few static methods inside of one of his class, I decided i didn't want to make mine static. 在编程过程中,无论哪种方式,程序员都在他的一个类中制作了一些静态方法,我决定我不想将我的方法设为静态。 Here is the code he writ below. 这是他在下面编写的代码。 I did mine all the same just with different references to the variables in the code like $this->variable. 我确实对所有相同的东西进行了挖掘,只是对代码中的变量的引用不同,例如$ this-> variable。

`<?php
// If it's going to need the database, then it's 
// probably smart to require it before we start.
require_once(LIB_PATH.DS.'database.php');

class Photograph extends DatabaseObject {

    protected static $table_name="photographs";
    protected static $db_fields=array('id', 'filename', 'type', 'size', 'caption');
    public $id;
    public $filename;
    public $type;
    public $size;
    public $caption;

    private $temp_path;
  protected $upload_dir="images";
  public $errors=array();

   protected $upload_errors = array(
        // http://www.php.net/manual/en/features.file-upload.errors.php
        UPLOAD_ERR_OK               => "No errors.",
        UPLOAD_ERR_INI_SIZE     => "Larger than upload_max_filesize.",
       UPLOAD_ERR_FORM_SIZE     => "Larger than form MAX_FILE_SIZE.",
       UPLOAD_ERR_PARTIAL       => "Partial upload.",
       UPLOAD_ERR_NO_FILE       => "No file.",
      UPLOAD_ERR_NO_TMP_DIR => "No temporary directory.",
      UPLOAD_ERR_CANT_WRITE => "Can't write to disk.",
      UPLOAD_ERR_EXTENSION  => "File upload stopped by extension."
    );

     // Pass in $_FILE(['uploaded_file']) as an argument
  public function attach_file($file) {
        // Perform error checking on the form parameters
        if(!$file || empty($file) || !is_array($file)) {
          // error: nothing uploaded or wrong argument usage
          $this->errors[] = "No file was uploaded.";
          return false;
         } elseif($file['error'] != 0) {
          // error: report what PHP says went wrong
          $this->errors[] = $this->upload_errors[$file['error']];
          return false;
        } else {
            // Set object attributes to the form parameters.
          $this->temp_path  = $file['tmp_name'];
          $this->filename   = basename($file['name']);
          $this->type       = $file['type'];
          $this->size       = $file['size'];
            // Don't worry about saving anything to the database yet.
             return true;

         }
    }

    public function save() {
        // A new record won't have an id yet.
        if(isset($this->id)) {
            // Really just to update the caption
            $this->update();
        } else {
            // Make sure there are no errors

            // Can't save if there are pre-existing errors
          if(!empty($this->errors)) { return false; }

            // Make sure the caption is not too long for the DB
          if(strlen($this->caption) > 255) {
                $this->errors[] = "The caption can only be 255 characters  long.";
                return false;
            }

          // Can't save without filename and temp location
          if(empty($this->filename) || empty($this->temp_path)) {
            $this->errors[] = "The file location was not available.";
            return false;
          }

            // Determine the target_path
          $target_path = SITE_ROOT .DS. 'public' .DS. $this->upload_dir .DS. $this->filename;

          // Make sure a file doesn't already exist in the target location
          if(file_exists($target_path)) {
            $this->errors[] = "The file {$this->filename} already exists.";
            return false;
          }

            // Attempt to move the file 
            if(move_uploaded_file($this->temp_path, $target_path)) {
            // Success
                 // Save a corresponding entry to the database
                if($this->create()) {
                    // We are done with temp_path, the file isn't there anymore
                     unset($this->temp_path);
                    return true;
                }
            } else {
                // File was not moved.
             $this->errors[] = "The file upload failed, possibly due to incorrect permissions on the upload folder.";
             return false;
            }
        }
    }

    public function destroy() {
        // First remove the database entry
        if($this->delete()) {
            // then remove the file
           // Note that even though the database entry is gone, this object 
            // is still around (which lets us use $this->image_path()).
              $target_path = SITE_ROOT.DS.'public'.DS.$this->image_path();
            return unlink($target_path) ? true : false;
        } else {
            // database delete failed
            return false;
        }
    }
     public function image_path() {
       return $this->upload_dir.DS.$this->filename;
    }

     public function size_as_text() {
        if($this->size < 1024) {
            return "{$this->size} bytes";
        } elseif($this->size < 1048576) {
            $size_kb = round($this->size/1024);
            return "{$size_kb} KB";
        } else {
            $size_mb = round($this->size/1048576, 1);
            return "{$size_mb} MB";
        }
    }


// Common Database Methods
public static function find_all() {
    return self::find_by_sql("SELECT * FROM ".self::$table_name);
  }

  public static function find_by_id($id=0) {
      global $database;
    $result_array = self::find_by_sql("SELECT * FROM ".self::$table_name."  WHERE id=".$database->escape_value($id)." LIMIT 1");
        return !empty($result_array) ? array_shift($result_array) : false;
  }

  public static function find_by_sql($sql="") {
     global $database;
    $result_set = $database->query($sql);
    $object_array = array();
    while ($row = $database->fetch_array($result_set)) {
       $object_array[] = self::instantiate($row);
    }
        return $object_array;
  }

    private static function instantiate($record) {
    // Could check that $record exists and is an array
$object = new self;
    // Simple, long-form approach:
    // $object->id              = $record['id'];
    // $object->username    = $record['username'];
    // $object->password    = $record['password'];
    // $object->first_name = $record['first_name'];
    // $object->last_name   = $record['last_name'];

    // More dynamic, short-form approach:
    foreach($record as $attribute=>$value){
      if($object->has_attribute($attribute)) {
        $object->$attribute = $value;
      }
    }
    return $object;
}

private function has_attribute($attribute) {
  // We don't care about the value, we just want to know if the key exists
  // Will return true or false
  return array_key_exists($attribute, $this->attributes());
}

protected function attributes() { 
    // return an array of attribute names and their values
  $attributes = array();
  foreach(self::$db_fields as $field) {
    if(property_exists($this, $field)) {
      $attributes[$field] = $this->$field;
    }
  }
  return $attributes;
}

protected function sanitized_attributes() {
  global $database;
  $clean_attributes = array();
  // sanitize the values before submitting
  // Note: does not alter the actual value of each attribute
  foreach($this->attributes() as $key => $value){
    $clean_attributes[$key] = $database->escape_value($value);
  }
  return $clean_attributes;
}

// replaced with a custom save()
// public function save() {
//   // A new record won't have an id yet.
//   return isset($this->id) ? $this->update() : $this->create();
// }

public function create() {
    global $database;
    // Don't forget your SQL syntax and good habits:
    // - INSERT INTO table (key, key) VALUES ('value', 'value')
    // - single-quotes around all values
    // - escape all values to prevent SQL injection
    $attributes = $this->sanitized_attributes();
  $sql = "INSERT INTO ".self::$table_name." (";
    $sql .= join(", ", array_keys($attributes));
  $sql .= ") VALUES ('";
    $sql .= join("', '", array_values($attributes));
    $sql .= "')";
  if($database->query($sql)) {
    $this->id = $database->insert_id();
    return true;
  } else {
    return false;
  }
}

public function update() {
  global $database;
    // Don't forget your SQL syntax and good habits:
    // - UPDATE table SET key='value', key='value' WHERE condition
    // - single-quotes around all values
    // - escape all values to prevent SQL injection
    $attributes = $this->sanitized_attributes();
    $attribute_pairs = array();
    foreach($attributes as $key => $value) {
      $attribute_pairs[] = "{$key}='{$value}'";
    }
    $sql = "UPDATE ".self::$table_name." SET ";
    $sql .= join(", ", $attribute_pairs);
    $sql .= " WHERE id=". $database->escape_value($this->id);
  $database->query($sql);
  return ($database->affected_rows() == 1) ? true : false;
}

public function delete() {
    global $database;
    // Don't forget your SQL syntax and good habits:
    // - DELETE FROM table WHERE condition LIMIT 1
    // - escape all values to prevent SQL injection
    // - use LIMIT 1
  $sql = "DELETE FROM ".self::$table_name;
  $sql .= " WHERE id=". $database->escape_value($this->id);
  $sql .= " LIMIT 1";
  $database->query($sql);
  return ($database->affected_rows() == 1) ? true : false;

    // NB: After deleting, the instance of User still 
    // exists, even though the database entry does not.
    // This can be useful, as in:
    //   echo $user->first_name . " was deleted";
    // but, for example, we can't call $user->update() 
    // after calling $user->delete().
}

}

?>`

^^This is his complete Photograph() class and below is my photograph class ^^这是他完整的Photograph()课,下面是我的照片课

<?php
//This class will use the database so wil need the database class included
require_once(LIB_PATH.DS.'database.php');
 class Photograph extends DatabaseObject
   {
            public $table_name = "photographs";

public $id;
public $filename;
public $type;
public $size;
public $caption;
public $all_photos = array();

private $temp_path;
protected $upload_dir = "images";

public $errors=array();

protected $upload_errors = array (
UPLOAD_ERR_OK =>            "No errors.",
UPLOAD_ERR_INI_SIZE =>      "Larger than upload_max_filesize.",
UPLOAD_ERR_FORM_SIZE =>     "Larger than form MAX_FILE_SIZE.",
UPLOAD_ERR_PARTIAL =>       "Partial Upload.",
UPLOAD_ERR_NO_FILE =>       "No File",
UPLOAD_ERR_NO_TMP_DIR =>    "No Temp Directory.",
UPLOAD_ERR_CANT_WRITE =>    "Cant write file to disk.",
UPLOAD_ERR_EXTENSION =>     "File uploaded stopped by extension."
);
//Pass in $_FILE['uploaded_file'] as an argument
public function attach_file($file) {
    //Perform error checking on the form params
    if(!$file || empty($file) || !is_array($file)) {
        //error: nothing uploaded or wrong argument
        $this->errors[] = "No file was uploaded.";
        return false;
    } elseif($file['error'] !=0) {
        //error: report what php says went wrong
        $this->errors[] = $this->upload_errors[$file['error']];
        return false;
    } else {
    //Set object attributes to the forms params
    $this->temp_path = $file['tmp_name'];
    $this->filename = basename($file['name']);
    $this->type = $file['type'];
    $this->size = $file['size'];
    //Dont worry about saving anything to database yet
    return true;
    }

}

public function save() {
    //A new record wont have an id yet
    if(isset($this->id)) {
        $this->update();
        //Really just to update the caption
    } else {
        //Make sure there are no errors
        //Cant save if there are pre existing errors
        if(!empty($this->errors)) { return false;}

        //Make suer the caption is not to long for the database
        if(strlen($this->caption) >= 255) {
            $this->errors[] = "The caption can only be 255 characters long.";
            return false;
        }

        //Cant save without the filename and temp location
        if(empty($this->filename) || empty($this->temp_path)) {
            $this->errors[] = "The file location was not available.";
            return false;
        }   

        //Determine the target path
        $target_path = SITE_ROOT .DS. 'public' .DS.$this->upload_dir . DS. $this->filename;

        //Make sure that the file doesn't already exist in that location
        if(file_exists($target_path)) {
            $this->errors[] = "The file {$this->filename} already exists.";
            return false;
        }


        //Attempt to move the file

        if(move_uploaded_file($this->temp_path, $target_path)) {
            //Success
            //Save a corresponding entry to the database
            if($this->create()) {
                //Were done with the temp path variable, The file isn't there any more
                unset($this->temp_path);
                return true;
            }
        } else {
        //Error File was not moved
        $this->errors[] = "The file upload failed, Possibly due to an incorrect permissions on upload folder.";
        return false;
        }

    }
}

public function destroy($id,$filename) {
    //First remove the database entry
    if($this->delete($id)) {
        //Then remove the file
        $target_path = SITE_ROOT.DS.'public'.DS.$this->upload_dir.DS.$filename;
        return unlink($target_path) ? true:false;
    } else {
        //Database delete failed
        return false;
    }

}

public function image_path() {
    return $this->upload_dir.DS;
}

public function size_as_text($file_size) {
    if($file_size < 1024) {
        return "{$file_size} bytes";
    } elseif($file_size < 1048576) {

        $size_kb = round($file_size/1024);
        return "{$size_kb} KB";

    } else {
        $size_mb = round($file_size/1048576, 1);
        return "{size_mb} MB";
    }
}

public function find_all() {
    global $database;
    $result = $this->find_by_sql("SELECT * FROM ".$this->table_name);
    return $result;
}

public function find_all_photos() {
    global $database;
    $query = "SELECT * FROM {$this->table_name}";
    $result = $database->query($query);

    return $result;
}

public function find_by_id($id=0) {
    global $database;

    $result_array = $this->find_by_sql("SELECT * FROM " . $this->table_name . " WHERE id={$database->escape_value($id)} LIMIT 1");
    return !empty($result_array) ? $result_array : false;
}

public function find_by_sql($sql="") {
    global $database;
    $result = $database->query($sql);
    $object_array = $database->fetch_array($result);
    $object = $this->instantiate($object_array);
    //while($row = $database->fetch_array($result)) {
        //$object_array[] = $this->instantiate($row);
    //}
    return $object_array;
}

private function instantiate($record) {

    //Could check if $record exists and is an array

    //Simple long form approach
     //$object = new self;
     $this->id= $record['id'];
     $this->filename    = $record['filename'];
     $this->type    = $record['type'];
     $this->size  = $record['size'];
     $this->caption   = $record['caption'];

    //More dynamic, Short form approach
    //foreach($record as $attribute=>$value) {
        //if($object->has_attribute($attribute)) {
            //$object->$attribute = $value;
        //}
    //}
    //return $object;
}

private function has_attribute($attribute) {
    //get_object_vars returns an assocative array with all attributes
    //Incl. pribate ones as the keys and their current values as the value
    $object_vars = get_object_vars($this);
    //We dont care about the value, we just want to know if the key exists
    //Will return true or false
    return array_key_exists($attribute,$object_vars);
}


public function create() {
    //This is the create method
    global $database;
    //DOnt forget your SQL syntax and good habits
    //INSERT INTO table (key,key) VALUES ('value','value')
    //SIngle-quotes around all values
    //Escape all values to prevent sql injection

    $query = "INSERT INTO {$this->table_name} (";
    $query .= "filename, type, size, caption";
    $query .= ") VALUES ('";
    $query .= $database->escape_value($this->filename) . "', '";
    $query .= $database->escape_value($this->type) . "', '";
    $query .= $database->escape_value($this->size) . "', '";
    $query .= $database->escape_value($this->caption) . "')";

    if($database->query($query)) {
        $this->id = $database->insert_id();
        return true;
    } else {
        return false;
    }
}

public function update() {
    global $database;
    //Dont forget your sql good habits
    //UPDATE table SET key='value', key='value' WHERE condition
    //single quotes around all values
    //Escape all values to prevent sql injection

    $query = "UPDATE {$this->table_name} SET ";
    $query .= "filename='" . $database->escape_value($this->filename) . "', ";
    $query .= "type='" . $database->escape_value($this->type) . "', ";
    $query .= "size='" . $database->escape_value($this->size) . "', ";
    $query .= "caption='" . $database->escape_value($this->caption) . "'";
    $query .= " WHERE id=" . $database->escape_value($this->id);
    $database->query($query);
    return ($database->affected_rows() ==1) ? true : false;

}

public function delete($id=0) {
    global $database;
    //Dont forget good sql habits
    //DELETE FROM table WHERE condition LIMIT 1
    //Escape all values to prevent sql injection 
    //Use limit 1

    $query = "DELETE FROM {$this->table_name} ";
    $query .="WHERE id=" . $database->escape_value($id);
    $query .= " LIMIT 1";
    $database ->query($query);
    return ($database->affected_rows() ==1) ? true:false;

    }

 }
?>

He then went onto using find_all() as to get all the contents from the photographs table on the view_photos.php page 然后,他继续使用find_all()从view_photos.php页面上的photos表中获取所有内容。

  $photos = Photograph::find_all();
?>
<?php include_layout_template('admin_header.php'); ?>

<h2>Photographs</h2>

<?php echo output_message($message); ?>
<table class="bordered">
  <tr>
    <th>Image</th>
    <th>Filename</th>
    <th>Caption</th>
    <th>Size</th>
    <th>Type</th>
    <th>&nbsp;</th>
  </tr>
<?php foreach($photos as $photo): ?>
  <tr>
    <td><img src="../<?php echo $photo->image_path(); ?>" width="100" />      </td>
    <td><?php echo $photo->filename; ?></td>
    <td><?php echo $photo->caption; ?></td>
    <td><?php echo $photo->size_as_text(); ?></td>
    <td><?php echo $photo->type; ?></td>
        <td><a href="delete_photo.php?id=<?php echo $photo->id; ?    >">Delete</a></td>
   </tr>
<?php endforeach; ?>

As you can see he makes a static call to the find_all() method and then loops through the array to list all of the photos from the database using the captured data stored in the photos variable, using all of the variables inside of the class. 如您所见,他静态调用find_all()方法,然后使用该类内部的所有变量,使用存储在photos变量中的捕获数据循环遍历数组以列出数据库中的所有照片。 below is my find_all() method. 下面是我的find_all()方法。

public function find_all() {
    global $database;
    $result = $this->find_by_sql("SELECT * FROM ".$this->table_name);
    return $result;
}

when i do the same thing but with an instance of the object Photograph 当我做同样的事情但带有对象Photograph的实例时

$photo_object = new Photograph();
$photos = find_all();

If i try and then do the same loop as he does i just get the same result again and again (There are currently 4 entries in the database and i get the exact same entry about 10 times) 如果我尝试然后执行与他相同的循环,我一次又一次地得到相同的结果(数据库中当前有4个条目,而我得到的完全相同的条目大约是10次)

Here is my code which results in that output 这是我的代码,导致该输出

<?php require_once("../../includes/initialize.php"); ?>
<?php if(!$session->is_logged_in()) { redirect_to("login.php");} ?>
<?php 

     //This is the class being called
    $photo_object = new Photograph();

     //Find all photos will return the result from the database. We then need to call the fetch array onit
     //$photos = $photo_object->find_all_photos();
    $photos = $photo_object->find_all();
?>


 <?php include_layout_template('admin_header.php'); ?>

<h2>Photographs: List</h2>
<?php echo output_message($message);?>
<table class="bordered">

<tr>
<th>Image</th>
<th>Filename</th>
<th>Caption</th>
<th>Size</th>
<th>Type</th>
<th>&nbsp;</th>
</tr>
  <?php foreach($photos as $photo): ?>
 <tr>
 <td><img src="<?php echo "../" . $photo_object->image_path() .     $photo_object->filename;?>" width="100" /></td>
<td><?php echo $photo_object->filename; ?></td>
 <td><?php echo $photo_object->caption; ?></td>
<td><?php echo $photo_object->size_as_text($photo_object->size); ?></td>
 <td><?php echo $photo_object->type ?></td>
<td><a href="delete_photo.php?id=<?php echo $photo_object->id;?>">Delete</a>    </td>
</tr>
 <?php endforeach; ?>

</table>
<br />
<a href="photo_upload.php">Upload a new photograph</a>

<?php include_layout_template('admin_footer.php'); ?>

The code above outputs 上面的代码输出

` Photo Gallery: Admin `图片库:管理员

Photo Gallery: Admin 相册:管理员

Photographs: List 照片:清单

<tr>
 <th>Image</th>
<th>Filename</th>
<th>Caption</th>
<th>Size</th>
<th>Type</th>
<th>&nbsp;</th>
 </tr>
 <tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
 <td>This is a photo of some bamboo</td>
<td>445 KB</td>
 <td>image/jpeg</td>
 <td><a href="delete_photo.php?id=1">Delete</a></td>
</tr>
 <tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
 <td>This is a photo of some bamboo</td>
<td>445 KB</td>
 <td>image/jpeg</td>
 <td><a href="delete_photo.php?id=1">Delete</a></td>
</tr>
<tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
 <td>445 KB</td>
 <td>image/jpeg</td>
<td><a href="delete_photo.php?id=1">Delete</a></td>
</tr>
<tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
<td>445 KB</td>
<td>image/jpeg</td>
<td><a href="delete_photo.php?id=1">Delete</a></td>
</tr>
<tr>
 <td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
 <td>This is a photo of some bamboo</td>
<td>445 KB</td>
<td>image/jpeg</td>
<td><a href="delete_photo.php?id=1">Delete</a></td>
 </tr>
<tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
<td>445 KB</td>
 <td>image/jpeg</td>
<td><a href="delete_photo.php?id=1">Delete</a></td>
</tr>
<tr>
  <td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
 <td>This is a photo of some bamboo</td>
 <td>445 KB</td>
 <td>image/jpeg</td>
 <td><a href="delete_photo.php?id=1">Delete</a></td>
</tr>
 <tr>
<td><img src="../images\bamboo.jpg" width="100" /></td>
 <td>bamboo.jpg</td>
<td>This is a photo of some bamboo</td>
 <td>445 KB</td>
<td>image/jpeg</td>
 <td><a href="delete_photo.php?id=1">Delete</a></td> 
 </tr>
 <tr>
 <td><img src="../images\bamboo.jpg" width="100" /></td>
<td>bamboo.jpg</td>
 <td>This is a photo of some bamboo</td>
 <td>445 KB</td>
 <td>image/jpeg</td>
 <td><a href="delete_photo.php?id=1">Delete</a></td>
 </tr>
  <tr>
 <td><img src="../images\bamboo.jpg" width="100" /></td>
 <td>bamboo.jpg</td>
 <td>This is a photo of some bamboo</td>
 <td>445 KB</td>
 <td>image/jpeg</td>
 <td><a href="delete_photo.php?id=1">Delete</a></td>
 </tr>

</table>
 <br />
 <a href="photo_upload.php">Upload a new photograph</a>

 </div>
 <div id="footer">Copyright 2015, Ryan Hadley</div>

 </body>
 </html>
`

Does this method have to be static ? 此方法必须是静态的吗? Or am i just not seeing something, I resolved it by writing a new method 还是我只是没看到什么,我通过编写新方法解决了

public function find_all_photos() {
    global $database;
    $query = "SELECT * FROM {$this->table_name}";
    $result = $database->query($query);

    return $result;
}

This works but i dont use any of the variables inside of the class instead i make a call to the photo array which i create in my foreach loop (foreach($photos as $photo)). 这有效,但是我不使用类内部的任何变量,而是调用了在我的foreach循环中创建的照片数组(foreach($ photos as $ photo))。 Which makes the attributes inside of the class seem very pointless. 这使得类内部的属性显得毫无意义。 Did i do this the right way ? 我这样做正确吗? Or is there something im just not understanding about objects ? 还是我只是不了解对象?

Thankyou in advance for any help i may get 预先感谢您为我提供的任何帮助

Happy coding 快乐编码

The code as you have it now, passes $object_array into instantiate . 您现在拥有的代码将$object_array传递给instantiate

But instantiate is built to accepts only one row retrieved from the resultset. 但是instantiate被构建为仅接受从结果集中检索的row

If you examine $object_array before passing it, you will know more about why you get the undesired results. 如果在传递$object_array之前对其进行检查,您将了解为什么会得到不想要的结果。

public function find_by_sql($sql="") {
    global $database;
    $result = $database->query($sql);
    $object_array = $database->fetch_array($result);

    // Examine $object_array:
    print '<pre>';
    var_dump($object_array);
    print '</pre>';

    $object = $this->instantiate($object_array);

    return $object_array;
}

About the following commented lines: 关于以下注释行:

 //while($row = $database->fetch_array($result)) {
        //$object_array[] = $this->instantiate($row);
    //}

I suggest uncommenting them and examine the $row 's: 我建议取消注释,并检查$row

 while( $row = $database->fetch_array($result) ) {

    // Examine $row:
    print '<pre>';
    print_r( $row );
    print '</pre>';

        //$object_array[] = $this->instantiate($row);
 }

About the function instantiate - The way you are using it now, every time it gets called, it sets the properties (id, filename ... etc) of itself. 关于函数instantiate -您现在使用它的方式,每次调用它时,都会设置其自身的属性(id,filename等) So the last time this function gets called, the values of the properties of the Photograph instance are the same as the ones from the last $record that has been passed to it. 因此,最后一次调用此函数时,Photograph实例的属性值与传递给它的最后一个$record的值相同。

private function instantiate($record) {

    //Could check if $record exists and is an array

    //Simple long form approach
     //$object = new self;
     $this->id= $record['id'];
     $this->filename    = $record['filename'];
     $this->type    = $record['type'];
     $this->size  = $record['size'];
     $this->caption   = $record['caption'];
}

This is a start to provide you insight about why you see 10 times the same result. 这是一个开始,可让您了解为何看到的结果是相同结果的10倍。

I wrote an example to illustrate how you go about to do what you are looking for (determining from your comments): 我写了一个例子来说明您将如何做(根据您的评论确定):

/**
 * A new class 'Photographs' to 'manage' the collection of photographs:
 **/
class Photographs {

    protected static $table_name="photographs";

    public $photographObjects = array();

    function __construct() {
        // The constructor runs on creation/instantiation of the 'Photographs' object

        print 'Photographs object created...';
    }

    // Retrieves the data and instantiates Photograph objects:
    public function get_photographs() {
        global $database;

        $sql = "SELECT * FROM ". $this->table_name;

        $this->photographObjects = array(); // empty the array before filling it

        $result = $database->query($sql);

        while( $row = $database->fetch_array( $result ) ) {
            $tmpPhotograph = new Photograph();
            $tmpPhotograph->id = $row['id'];
            $tmpPhotograph->filename = $row['filename'];
            // etc etc (or make the 'instantiate' function of the 'Photograph' class public, so you can do:
            // $tmpPhotograph->instantiate($row);
            // Now add a created and initialized object to your array:
            $this->photographObjects[] = $tmpPhotograph;
        }
    }


    // render the photographs:
    public function render_photographs() {

        if ( count($this->photographObjects) > 0 ) { 
            // loop through the objects in the photograpsObjects array:

            foreach ( $this->photographObjects as $tmpPhotograph ) {
                // in this line you can see that public properties (filename), and functions (image_path()) are available:
                print '<img src="../' . $tmpPhotograph->image_path() .     $tmpPhotograph->filename . '" width="100" />';

            }
        } else {
            // Nothing found, inform the user:
            print 'No photographs in array';
        }
    }



}

To use: 使用方法:

$photographManager = new Photographs();
$photographManager->get_photographs(); // retrieve them

$photographManager->render_photographs(); // output them

or when you want to use your line: 或您想使用线路时:

<?php foreach($photos as $photo): ?>

You could do this: 您可以这样做:

<?php foreach( $photographManager->photographObjects as $photo ): ?>

I hope this clears up some things for you. 我希望这可以为您解决一些问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM