1

我已经开始将 PHP 项目重新编码为 OOP。我无法解决的一件事是如何制作动态选择列表。我有很多查找选择列表要制作。最好的方法是什么?

我创建了一个包含所有通用数据库查询的 DatabaseObject 类。我是在此处添加它们还是为它们创建一个特殊的类,以及如何进行编码?

require_once("database.php");

class DatabaseObject {

protected static $table_name;

// find all from a specific table
public static function find_all(){      
    global $database;
    return static::find_by_sql("SELECT * FROM ".static::$table_name);       
}

// select all from a specific table
public static function find_all_from($table){       
    global $database;
    return static::find_by_sql("SELECT * FROM " .$table);       
}

// find all from a specific table
public static function find_by_id($id){

    global $database;
    $result_array = static::find_by_sql("
    SELECT * FROM ".static::$table_name. " WHERE id = '{$id}' LIMIT 1");

    // return the data only for the one user
    return !empty($result_array) ? array_shift($result_array) : false;      
}

// find using sql
public static function find_by_sql($sql=""){

    global $database;
    // return all data from sql
    $result_set = $database->query($sql);
    $object_array = array();
    while($row = $database->fetch_array($result_set)){
        $object_array[] = static::instantiate($row);    
    }
    return $object_array;       
}


protected static function instantiate($record){

    $class_name = get_called_class();
    $object = new $class_name;

    foreach($record as $attribute=>$value){
        if($object->has_attribute($attribute)){
            $object->$attribute = $value;
        }
    }
    return $object;
}


protected function has_attribute($attribute){

$object_vars =  $this->attributes();

// here we only want to know if the key exist
// so we will return true or false
return array_key_exists($attribute, $object_vars);      
}

protected function attributes() {

$attributes = array();
foreach(static::$db_fields as $field) {
    if(property_exists($this,$field)) {
    $attributes[$field]= $this->$field; 
    }
}
return $attributes; 
}

protected function sanitised_attributes() {
global $database;
$clean_attributes = array();
foreach($this->attributes() as $key => $value){
$clean_attributes[$key] = $database->escape_value($value);  
}
return $clean_attributes;   
}


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

// create new  
protected function create() {
global $database;
$attributes =$this->sanitised_attributes();

$sql  = "INSERT INTO ".static::$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;
}
}

// update details
protected function update() {
global $database;
$attributes =$this->sanitised_attributes();
$attribute_pairs = array();
foreach($attributes as $key => $value) {
    $attribute_pairs[] = "{$key}='{$value}'";   
}
$sql  = "UPDATE " .static::$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;

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

4 回答 4

1

我肯定会将选择列表建模为一个对象,因为它具有可以封装的明确定义的职责。我会尽量保持它与类的分离,DatabaseObject以便这些类中的任何一个的更改都不会影响另一个。例如,考虑:

class SelectList
{
    protected $options;
    protected $name;

    public function __construct($name, $options)
    {
         $this->options = $options;
         $this->name = $name;
    }

    public function render()
    {
        $html = "<select name='" . $this->name . "'>\n";
        foreach ($this->options as $option) 
        {
            $html .= $option->render();
        }
        $html .= "</select>\n";
        return $html;
    }
}

class SelectListOption
{
    protected $label;
    protected $value;
    protected $isSelected;

    public function __construct($label, $value, $isSelected = false)
    {
      //Assign the properties
    }

    public function render()
    {
        $html .= '<option value="' . $this->value . '"';
        if ($this->isSelected)
        {
         $html .= ' selected="selected" ';
        }
       $html .= '>' . $this->label . "</option>\n";
    }
}

我喜欢以这种方式建模的一件事是添加新功能(例如选定/未选定项目的 CSS 样式或禁用属性)非常容易,因为您知道新功能属于哪个对象。此外,拥有这种“小”对象可以很容易地编写单元测试。

高温高压

于 2012-11-05T13:38:20.827 回答
0

您还可以添加选定的选项功能

公共静态函数 viewSelect($name = "select", $arr_options = array(), $selected) {

$selectedhtml = "";
$html = "<select name='$name'>\n";
foreach ($arr_options as $key => $val) {

if($key == $selected) $selectedhtml = "selected";

    $html .= "<option value='$key' $selectedhtml>$val</option>\n";
}
$html .= "</select>\n";
return $html; }
于 2012-11-05T06:30:40.943 回答
0

只需通过迭代传递给该方法的关联数组来创建一个返回 HTML 选择/选项视图的方法...?可能是这样的:

public static function viewSelect($name = "select", $arr_options = array()) {
    $html = "<select name='$name'>\n";
    foreach ($arr_options as $key => $val) {
        $html .= "<option value='$key'>$val</option>\n";
    }
    $html .= "</select>\n";
    return $html;
}

然后只需将其中一个数据库查询的结果传递给此方法。您可以将此方法放入您想要的任何适当的类中。

于 2012-11-04T17:50:15.823 回答
0
public function get_posts()
{
    $query="select * from tbl_posts";
    $result=  mysql_query($query);
    $i=0;
    while($data=  mysql_fetch_assoc($result))
    {
        foreach($data as $key=>$value)
        {
            $info[$i][$key]=$value;
        }
        $i++;
    }
    return $info;


}
于 2013-03-28T16:48:01.267 回答