【问题标题】:Looking for help to make a select statement dynamic寻求帮助以使选择语句动态化
【发布时间】:2021-01-23 04:47:55
【问题描述】:

我想创建一个动态选择语句,它可以选择我要求的任何表,与我数据库中的表列相同。

这是我目前选择的课程:

<?php

   class select extends database{
    // Instance variables
    private $id;
    public $table;
    public $column;
    public $sql;
    public $result = array();

    // Methods - Behavior
    public function selectQuery($table){
        
        global $con;
        
        $sql = $this->sql;
        
        $sql = "SELECT * FROM {$table}";
        
        $result = $this->con->query($sql);
        
        while($row = $result->fetch_object()){
            //iterate all columns from the selected table 
            //and return it someway.
        }
    }
}
$selectQuery = new select();

这是我的数据库类

require_once(LIB_PATH.DS."config.php");
class database
{
    public $con;
    public $result = array();

    public function __construct()
    {
        $this->con = new mysqli(DB_HOST,DB_USERNAME,DB_PASSWORD,DB);
        if($this->con->connect_error){
            die($this->con->connect_error);
        }
    }
}
$db = new database();

到目前为止,我正在做的是使用 mysqli 连接到我的数据库,然后我从我的数据库类中扩展我的选择类,这样我就可以获得连接,然后我想从中选择全部。

【问题讨论】:

  • 你的$table和array是什么?还是只是一个表名?
  • 您不需要在类文件本身中实例化您的databaseselect 类(即$db = new database(); 在数据库类文件中是多余的)。只需在需要时/在需要时实例化对象即可。
  • 另外,从selectQuery方法中删除global $con;...因为select extends database你的mysqli连接($con)在选择类中通过$this-&gt;con可用(因为它有公共可见性......虽然应该受到保护)。
  • 你不必在类中返回连接吗?
  • 不,它是在database 构造函数中设置的;因为select类扩展了database类,当select被实例化时database::__construct()应该被调用。

标签: php sql mysqli


【解决方案1】:

首先,您的select 类扩展了database 类,因此在select 类中重新声明public $result = array(); 没有意义,实际上甚至没有必要。

其次,由于您没有在类之外使用对象属性,因此将它们设为private

最后,由于您要处理可变数量的参数,请使用func_get_args() 函数。

这是参考:

根据您的要求,解决方案是将可变数量的参数发送到 selectQuery() 方法并使用 func_get_args() 获取包含函数参数列表的数组。

  • 第一个参数是表名,其余参数是列名(如果提供)
  • 如果只向函数传递一个参数,则SELECT 查询将为SELECT * FROM table_name
  • 如果将多个参数传递给函数,则SELECT 查询将为SELECT column1, column2, column3, ... FROM table_name

所以你的代码应该是这样的:

require_once(LIB_PATH.DS."config.php");

class database
{
    public $con;

    public function __construct()
    {
        $this->con = new mysqli(DB_HOST,DB_USERNAME,DB_PASSWORD,DB);
        if($this->con->connect_error){
            die($this->con->connect_error);
        }
    }
}

class select extends database{
    // Instance variables
    private $table;
    private $columns;
    private $sql;

    // Methods - Behavior
    public function selectQuery(){

        // incrementally construct the query
        $this->sql = "SELECT ";

        // get the argments passed to the function
        $this->columns = func_get_args();

        // the first argument would be the table name and rest of the arguments are coolumn names(if provided)
        $this->table = $this->columns[0];

        // if only one argument is passed to the function,
        // then SELECT query would be SELECT * FROM table_name
        if(count($this->columns) == 1){
            $this->sql .= "* ";
        }else{

            // if more than one argument is passed to the function,
            // then the SELECT query would be SELECT column1, column2, column3, ... FROM table_name
            for($i = 1; $i < count($this->columns); ++$i){
                $this->sql .= $this->columns[$i] . ",";
            }

            // remove the last , from the $sql string
            $this->sql = rtrim($this->sql, ",");
        }

        $this->sql .= " FROM $this->table";

        // execute the query
        $result = $this->con->query($this->sql);

        // return the result set
        return $result;
    }
}

$obj = new select();

$table = "YOUR_TABLE_NAME";
$column1 = "COLUMN_1";
$column2 = "COLUMN_2";

$result = $obj->selectQuery($table, $column1, $column2);
while($row = $result->fetch_assoc()){
    // display it
    echo $row[$column1] . " " . $row[$column2] . "<br />";
}

$result = $obj->selectQuery($table);
while($row = $result->fetch_assoc()){
    // display it
}

【讨论】:

  • 非常感谢。这给了我一些启示。
  • @TobiasMadsen 很高兴我能帮上忙。您已获得 2 个答案,请接受适合您或解决您的问题的答案。 How to accept answer on Stack Overflow
【解决方案2】:

这很简单

function conx(){

$link = new mysqli($db_host, $db_user, $db_pass, $db_name);

if ($link->connect_error) {
    die("Connection failed: " . $link->connect_error);
} 
 $sql = "SET NAMES utf8"; 
 $result = $link->query($sql); 
return $link;
}

现在你有了一个连接,让我们传递一个 $table 值

$link = conx();
$sql = "SELECT * FROM $table";  <------ REMOVE {} from your table var!Worked for me
$result = $link->query($sql);
if(!$result) {echo 'Failed to query';};
if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo $row["title"];
    }
} 
else {
    echo "0 results";
}
$link->close();
}

这是最基本的!

【讨论】:

  • 在将大括号插入字符串时,尤其是在类中,将花括号放在 var 周围可以说是一种很好的做法:例如"SELECT * FROM {$this-&gt;table}" - 它确保变量被评估。
【解决方案3】:

实际上 - 我不认为你离得很远;暂时忽略命名空间或任何特定的设计模式,存在一些范围弱点,但是...

让我们假设一个目录结构,其中有你的类和一个应用程序文件(例如 index.php)将它们粘合在一起:

/class/Database.php

<?php

class Database {
    protected $con;

    public function __construct() {
        $this->con = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB);

        //error trapping
        if($this->con->connect_error) {
            die($this->con->connect_error);
        }

        //ok set charset; should add error trapping here too
        else {
            $this->con->set_charset('UTF8'); //probably
        }
    }
}

/class/Select.php

<?php

class Select extends Database {

    // Class Members
    private $id;
    public $table;
    public $column;
    public $sql;
    public $result = array();

    // Methods - Behavior
    public function __construct() {
        parent::__construct();
    }

    public function selectQuery($table) {

        //since there's a $table class member... 
        $this->table = $this->con->real_escape_string($table);

        //query string
        $sql = "SELECT * FROM {$this->table}";

        //should be some error trapping here
        $response = $this->con->query($sql);

        //result
        while($row = $response->fetch_object()) {
            $this->result[] = $row;
        }

        //return
        return $this->result;
    }
}

index.php

<?php

//require is a language construct not a function
// - it doesn't need parentheses
require_once LIB_PATH.DS . 'config.php';
require_once '/path/to/class/Database.php';
require_once '/path/to/class/Select.php';

//build the object and run the query
$s = new Select;

// this should hold your resultset as an array of objects
// though it would also be accessible via $s->result since
// that's a public class member
$r = $s->selectQuery('my_table'); 

虽然这都是非常简单的,而且不是很实用(但你说这是为了考试,所以......)。

实际上,您可能不想为每个查询建立一个新的数据库连接,因此可能值得关注static 类成员:http://php.net/manual/en/language.oop5.static.php

... 或单例模式(尽管您可能需要也可能不想要单例数据库连接):http://www.phptherightway.com/pages/Design-Patterns.html

...也是封装,public 类成员不是(通常)可取的:What is encapsulation with simple example in php?

【讨论】:

    【解决方案4】:

    db_connection.php

    class db{
        private $db_host = '';
        private $db_user = 'user';
        private $db_pass = 'pass';
        private $db_name = 'your database name';
        protected $con;
    
        public function __construct(){
            $this->con = new mysqli($this->db_host,$this->db_user,$this->db_pass,$this->db_name);
            if ($this->con -> connect_errno) {
              echo "Failed to connect to MySQL: " . $this->con -> connect_error;
              exit();
            }
            return false;
        }
    
    }    
    

    查询.php

    require 'db_connection.php';
    class query extends db{
        public function select($tableName,$column = null,$clause = null){
            $columns = null;
            if ($column == null) {
                $columns = '*';
            }else{
                $values = Array();
                foreach($column as $key => $value){
                  array_push($values,"$value");
                }
                $columns = join(',',$values);
            }
            $select = null;
            $select .= "SELECT ".$columns." FROM {$tableName} ";
            if ($clause != null) {
                $select .= $clause;
            }
            $s_sql =  $this->con->prepare($select);
            $s_sql->execute();
            // It will return mysqli_stmt Object
            return $s_sql;
        }   
    
    }
    

    $s 将返回 mysqli_stmt 对象。

    index.php

    $query_ob = new query();
    // The first parameter is required And other parameters is optional. 
    // The second parameter must be Array[].
    $s = $query_ob->select(parameter1,parameter1,parameter3);     
    $r = $s->get_result();
    while ($f = $r->fetch_assoc()) {
        // code here
    }
    $t->close();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-07
      • 1970-01-01
      • 1970-01-01
      • 2016-10-01
      相关资源
      最近更新 更多