PHP-使用PDO向my DB查询方法传递参数

PHP-使用PDO向my DB查询方法传递参数,php,Php,我不熟悉PHP和OOP,我正在构建方法以便从文章数据库收集文章,我的方法将收到三个参数:$limit、$category、$order。我认为这是不言自明的,但我有几个问题 -如果缺少一个参数,该方法会返回false吗?我怎样才能避免这种情况 -我不知道如何从两个相关的表中收集属性,也就是说,每篇文章都属于一个类别 -我是否应该将我正在构建的每一种方法都放在一个try-cath条款中,这对我是有利的还是我的if-elses会起作用 -我做参数绑定对吗?或者我应该指定我认为应该是变量类型的第三个参

我不熟悉PHP和OOP,我正在构建方法以便从文章数据库收集文章,我的方法将收到三个参数:$limit、$category、$order。我认为这是不言自明的,但我有几个问题

-如果缺少一个参数,该方法会返回false吗?我怎样才能避免这种情况

-我不知道如何从两个相关的表中收集属性,也就是说,每篇文章都属于一个类别

-我是否应该将我正在构建的每一种方法都放在一个try-cath条款中,这对我是有利的还是我的if-elses会起作用

-我做参数绑定对吗?或者我应该指定我认为应该是变量类型的第三个参数,但是如果引入的var与预期类型不同呢

这是我的相关表格,我想我正确地设置了它们的关系

类别表

CREATE TABLE articles
(
  id                     SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,  -- Each article unique identifier:
  categoryId             SMALLINT UNSIGNED NOT NULL,                 -- The artcle category id:
  image                  VARCHAR(255) NULL DEFAULT 'images/img_default_article.jpg',                      -- Main image of the article:
  title                  TEXT NOT NULL,                              -- Full title of the article:
  summary                TEXT NOT NULL,                              -- The summary of the article:
  content                MEDIUMTEXT NOT NULL,                        -- The HTML content of the article:
  created                DATE NOT NULL,                              -- Day and Month the article entry was created
  modified               TIMESTAMP  NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, --Timestamp the article was last edited
  visible                INT(11) NOT NULL,                           -- 1 - Visible, 0 - Not visible:


  PRIMARY KEY     (id)
  FOREIGN KEY     (categoryId) REFERENCES categories(id) ON UPDATE CASCADE ON DELETE CASCADE
)

ENGINE=innoDB DEFAULT CHARSET=utf8 COMMENT='all the articles available';
文章表

CREATE TABLE categories
(
  id              SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,         -- Category unique identifier
  image           TEXT NOT NULL DEFAULT "images/img_default_category.jpg",    -- Image of the article
  name            VARCHAR(255) NOT NULL,                             -- Name of the category:
  description     TEXT NOT NULL,                                     -- A short description of the category:

  PRIMARY KEY     (id)
)

ENGINE=innoDB DEFAULT CHARSET=utf8 COMMENT="Categories for all th articles";
PHP代码:

<?php
class Article extends BaseEntity{
    private $id, $categoryid, $author, $image, $title, $summary, $content, $created, $modified, $visible;

    public function __construct($adapter) {
        $table="articles";
        parent::__construct($table, $adapter);
    }



    public function getArticlesAdv($limit, $category, $order){
        $sql = "SELECT *
                FROM articles
                ORDER BY created DESC";

        $stmt = $this->db->prepare($sql);
        $stmt->execute();
        if($stmt->execute()){

            $numrows = $stmt->rowCount();
            if(numrows>0){

                while ($row = $query->fetchAll(PDO::FETCH_OBJ))
                {
                $resultSet[]=$row;
                }
                return $resultSet;

            }
            else
            {   
            return false;
            }   
        }

        else
        {
        return false;   
        }
    }

    public function getAllArticles(){
        $sql = "SELECT *
                FROM articles
                ORDER BY created DESC";

        $stmt = $this->db->prepare($sql);

        $stmt->execute();

        $numrows = $stmt->rowCount();

        if(numrows>0){

        while ($row = $query->fetchAll(PDO::FETCH_OBJ)) {
           $resultSet[]=$row;
        }

        return $resultSet;

        }
        else{
            return false;
        }


    }

?>

首先,我向您推荐一些文档:

PHP OOP:

PHP PDO:

目前您没有使用($limit、$category、$order)。 为了使它们成为可选的,您必须在函数声明中设置一个默认值:

public function getArticlesAdv($limit = 10, $category = null, $order = 'articles.id'){
订单本身是不够的(按…ASC/DESC订购),因此我将使用以下内容修改您的函数:

public function getArticlesAdv($limit = 10, $category = null, $order = 'articles.id', $orderType = 'asc'){
修改后,需要创建适当的SQL语句:

 $where = "";
 if($category){
    $where = " where categoryID = $category ";
  }

  $sql = "SELECT a.*,c*
          FROM articles a join categories c on a.categoryID = c.id 
          $where              
          ORDER BY $order $orderType $limit";
我把a.*,c.*放在这里,因为否则会出现歧义错误(与限制相同)

这只是众多方法之一


希望能有所帮助。

回答I-III:根据您的
PDO::ATTR_ERRMODE
设置为
PDO::ERRMODE_EXCEPTION
,您可能需要设置try-catch或只需检查
PDO::errorCode()
至于缺少任何参数的结果
PDO::ATTR_ERRMODE
将决定您收到的是异常还是空集或空值

答案II:要从两个或多个表中收集数据,可以使用。表的一个示例可能是:

SELECT `a`.`title`, `c`.`name` AS `category_name` FROM `articles` AS `a` INNER JOIN `categories` AS `c` ON (`a`.`categoryId` = `c`.`id`);
c
name
AS
category\u name

这称为别名,无论是在列上还是在表上,只要
alias
alias,就可以在查询的任何位置使用别名,而不是实际名称

内部联接
categories
AS
c
ON(
a
categoryId
=
c
id

这意味着从表
categories
中获取相应的数据,该表别名为
c
,其中
articles
表中的
categoryId
列等于
categories
表中的
id

答案IV:根据您是否为mysql服务器启用了严格模式,不在int列上使用第三个参数(默认为
PDO::PARAM_STR
)将导致错误。 即使没有设置严格模式,但发送了错误类型的变量类型声明,例如在int列而不是
1
PDO::PARAM_STR
)上发送
'1'
),如果在该列上有索引,查询将不会使用索引,从而导致性能低下

我在您的代码中看不到任何绑定,但请记住,PDO中有3种类型的绑定可用,分别是、和

我将以
bindValue
为例,因为它们之间的差异或sll类型的使用风格不在此上下文中

public function getArticlesAdv($limit, $category, $order){
    $sql = "SELECT * FROM articles WHERE `categoryId` = :category ORDER BY ";
    switch($order) {
       case 'categoryId':
           $sql .="categoryId";
           break;
       case 'visible':
           $sql .="categoryId";
           break;
       default:
           $sql .="id";
           break;
    }
    $sql .= ' DESC LIMIT 0,:limit';

    $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    try {
        $stmt = $this->db->prepare($sql);
        $stmt->bindValue($category,':category',PDO::PARAM_INT);
        $stmt->bindValue($limit,':limit',PDO::PARAM_INT);
        $stmt->execute();
        $resultSet = $stmt->fetchAll(PDO::FETCH_OBJ);
        if ($resultSet) return $resultSet;
        return array();
     catch(Exception $ex) {
        return array();
     }
}
这有点像很多问题都集中在一个问题上,基本上是问你是否做对了(而不是试图修复一个坏东西)。。。这实际上可能更适合于