如何从另一个功能中的另一个文件访问连接功能

时间:2018-07-01 17:08:47

标签: php

这里的问题是viewauthor.php认为$conn是未定义的变量。这也给我一个错误,指出在mysqli_query() expects parameter 1 to be mysqli, null given in行中有$results。如何使viewauthor.php访问dbconnect.php文件中的$conn

这是db.connect.php中的代码

   <?php
    class dbconn {
    public function dbcon() {
        global $conn;
        $conn = new mysqli('localhost','root','','bookinventory') or die 
        ('Error connecting to mysql' .mysqli_error());
        return $conn;

    }
}
?>

这是viewauthor.php中的代码

    <?php
    require_once 'dbconnect.php';

    class author {
     $con = new dbconn();
     $conn = $con->dbcon();

    public function viewAuthor() {  
    $query = ("SELECT * FROM author");
    $results = mysqli_query($conn,$query);
    $authors = array();

            while($author = mysqli_fetch_object($results)) {
            $authors[] = $author;
      }
            return $authors;
    }
 }
 ?>

1 个答案:

答案 0 :(得分:2)

发现的问题:

  • 请参见$con = new dbconn():要定义类的属性,请使用关键字 public protected private ,< em> static ,常量等,然后是普通变量声明。 参见Properties
  • 请参见$con = new dbconn():您不能将对象创建为属性定义的一部分。该属性值必须是一个常量表达式,而不是(例如)变量,属性或函数调用。参见PropertiesClass Constants
  • 请参见$results = mysqli_query($conn, $query);:为什么会收到错误“ mysqli_query()期望参数1为mysqli,在...中给出空值” ?因为您正在尝试引用$conn,但是在viewAuthor方法的定义中它既未定义为参数-如viewAuthor($conn) {...},也未正确定义为类属性-如果是您必须像这样引用它:$results = mysqli_query($this->conn, $query);

现在,我将尝试为您提供两种正确的选择。但是只有第二个是推荐的。而且,我将尽量简化我的解释。注意我的命名和编码约定,包括更改后的表名,页面名,连接页面的require语句等。也不要忘记使用以下命令更改页面connection.php中的数据库凭据你的。

但是,首先,一些建议

  • 不要使用类来连接数据库。只需使用正确的连接性代码创建一个包含文件(请参见connection.php)。
  • 为每个需要访问数据库的类创建一个constructor,并为要作为参数传递的连接对象定义一个参数。此传递步骤称为dependency injection
  • 包括require时,使用require_once代替connection.php
  • 使用面向对象的mysqli,而不是过程性的。 php.net上描述的每个mysqli程序函数也都有一个面向对象的样式。
  • 重要:使用prepared statements,而不仅仅是使用mysqli_query直接查询数据库。另请参见this
  • 重要:阅读thisthis以正确应用错误处理。例如。优雅安全地摆脱die(...)mysqli_error()等。
  • 重要:实施自动加载器,或者更好的方法是使用Composer库。也实现名称空间。阅读PSR-1PSR-2PSR-4,并及时阅读PHP-FIG的其他建议。

替代1:

在下面的代码中,这一点变得很明显,为什么这种选择不是一个好的选择:

  • 类型为Author的对象(实际上应该仅是一个表行的表示形式)用于获取作者集合。甚至被提取为stdClass类型的对象的集合。不好
  • 类型为Author的对象负责查询数据库。实际上,为什么Author类型的对象与数据库有关?不好

connection.php

<?php

// Db configs.
define('HOST', 'localhost');
define('PORT', 3306);
define('DATABASE', 'tests');
define('USERNAME', 'root');
define('PASSWORD', 'root');

/*
 * Enable internal report functions. This enables the exception handling,
 * e.g. mysqli will not throw PHP warnings anymore, but mysqli exceptions
 * (mysqli_sql_exception).
 *
 * MYSQLI_REPORT_ERROR: Report errors from mysqli function calls.
 * MYSQLI_REPORT_STRICT: Throw a mysqli_sql_exception for errors instead of warnings.
 *
 * @link http://php.net/manual/en/class.mysqli-driver.php
 * @link http://php.net/manual/en/mysqli-driver.report-mode.php
 * @link http://php.net/manual/en/mysqli.constants.php
 */
$mysqliDriver = new mysqli_driver();
$mysqliDriver->report_mode = (MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

/*
 * Create a new db connection.
 *
 * @see http://php.net/manual/en/mysqli.construct.php
 */
$connection = new mysqli(HOST, USERNAME, PASSWORD, DATABASE, PORT);

Author.php:

<?php

class Author {

    /**
     * Database connection.
     *
     * @var mysqli
     */
    private $connection;

    /**
     *
     * @param mysqli $connection Database connection.
     */
    public function __construct(mysqli $connection) {
        $this->connection = $connection;
    }

    /**
     * Get all authors.
     *
     * @return stdClass[] The authors list.
     */
    public function getAllAuthors() {
        /*
         * The SQL statement to be prepared.
         *
         * @link http://php.net/manual/en/mysqli.prepare.php
         */
        $sql = 'SELECT * FROM authors';

        /*
         * Prepare the SQL statement for execution.
         *
         * @link http://php.net/manual/en/mysqli.prepare.php
         */
        $statement = $this->connection->prepare($sql);

        /*
         * Execute the prepared SQL statement.
         * When executed any parameter markers which exist will
         * automatically be replaced with the appropriate data.
         *
         * @link http://php.net/manual/en/mysqli-stmt.execute.php
         */
        $statement->execute();

        /*
         * Get the result set from the prepared statement.
         *
         * NOTA BENE:
         * Available only with mysqlnd ("MySQL Native Driver")! If this
         * is not installed, then uncomment "extension=php_mysqli_mysqlnd.dll" in
         * PHP config file (php.ini) and restart web server (I assume Apache) and
         * mysql service. Or use the following functions instead:
         * mysqli_stmt::store_result + mysqli_stmt::bind_result + mysqli_stmt::fetch.
         *
         * @link http://php.net/manual/en/mysqli-stmt.get-result.php
         * @link https://stackoverflow.com/questions/8321096/call-to-undefined-method-mysqli-stmtget-result
         */
        $result = $statement->get_result();

        // Fetch the data into a stdClass[] array.
        $rows = [];
        while ($row = $result->fetch_object()) {
            $rows[] = $row;
        }

        return $rows;
    }

    /**
     * Get an author by id.
     *
     * @param int $authorId Author id.
     * @return stdClass The author.
     */
    public function getAuthorById(int $authorId) {
        /*
         * The SQL statement to be prepared. Notice the so-called markers,
         * e.g. the "?" signs. They will be replaced later with the
         * corresponding values when using mysqli_stmt::bind_param.
         *
         * @link http://php.net/manual/en/mysqli.prepare.php
         */
        $sql = 'SELECT *
                FROM authors
                WHERE id = ?
                LIMIT 1';

        $statement = $this->connection->prepare($sql);

        /*
         * Bind variables for the parameter markers (?) in the
         * SQL statement that was passed to prepare(). The first
         * argument of bind_param() is a string that contains one
         * or more characters which specify the types for the
         * corresponding bind variables.
         *
         * @link http://php.net/manual/en/mysqli-stmt.bind-param.php
         */
        $statement->bind_param('i', $authorId);

        $statement->execute();
        $result = $statement->get_result();

        // Fetch the data into a stdClass object.
        $row = $result->fetch_object();

        return $row;
    }

}

index.php:

<?php

require 'connection.php';
require_once 'Author.php';

$author = new Author($connection);

/*
 * ================================
 * Example 1: Get all authors.
 * ================================
 */

// Get all authors.
$theAuthors = $author->getAllAuthors();

// Print the results.
echo '<b>Example 1: The whole authors list:</b>';
echo '<br/></br/>';
foreach ($theAuthors as $theAuthor) {
    echo $theAuthor->id . ' - ' . $theAuthor->first_name . ', ' . $theAuthor->last_name . '<br/>';
}

echo '<br/><hr/><br/>';

/*
 * ================================
 * Example 2: Get an author by id.
 * ================================
 */

// Get an author by id.
$theAuthor = $author->getAuthorById(2);

// Print the results.
echo '<b>Example 2: One selected author:</b>';
echo '<br/><br/>';
echo $theAuthor->id . ' - ' . $theAuthor->first_name . ', ' . $theAuthor->last_name . '<br/>';

替代2:

让我们更改上面的代码以具有更多的语义和结构意义。为此,请将类型Author的对象视为一个实体,其唯一目的是保留作者的特征并根据需要对其进行操作。这类对象称为域对象,仅负责business logic。请参阅this答案。因此,Author对象应该与数据库或任何其他持久层(会话,文件系统等)无关。实际上,它应该完全不知道获取其属性的位置和方式。

因此,将查询数据库,获取作者特征(例如,authors表中特定行的字段值)并将它们分配给Author对象的职责应推迟到-称为data mapper

因此,您所用的代码如下所示:

connection.php:

与上面相同。

Author.php:

<?php

class Author {

    /**
     * Author id.
     *
     * @var int
     */
    private $id;

    /**
     * First name.
     *
     * @var string
     */
    private $firstName;

    /**
     * Last name.
     *
     * @var string
     */
    private $lastName;

    /**
     * Get the name as 'John, Doe'.
     *
     * @return string The name.
     */
    public function getName() {
        return $this->firstName . ', ' . $this->lastName;
    }

    /**
     * Get the id.
     *
     * @return int
     */
    public function getId() {
        return $this->id;
    }

    /**
     * Set the id.
     *
     * @param int $id Id.
     * @return $this
     */
    public function setId($id) {
        $this->id = $id;
        return $this;
    }

    /**
     * Get the first name.
     *
     * @return string
     */
    public function getFirstName() {
        return $this->firstName;
    }

    /**
     * Set the first name.
     *
     * @param string $firstName First name.
     * @return $this
     */
    public function setFirstName($firstName) {
        $this->firstName = $firstName;
        return $this;
    }

    /**
     * Get the last name.
     *
     * @return string
     */
    public function getLastName() {
        return $this->lastName;
    }

    /**
     * Set the last name.
     *
     * @param string $lastName Last name.
     * @return $this
     */
    public function setLastName($lastName) {
        $this->lastName = $lastName;
        return $this;
    }

}

AuthorMapper.php:

<?php

require_once 'Author.php';

class AuthorMapper {

    /**
     * Database connecton.
     *
     * @var mysqli
     */
    private $connection;

    /**
     * Authors collection.
     *
     * @var Author[]
     */
    private $authorsCollection = [];

    /**
     *
     * @param mysqli $connection Database connection.
     */
    public function __construct(mysqli $connection) {
        $this->connection = $connection;
    }

    /**
     * Get all authors.
     *
     * @return array Authors list.
     */
    public function getAllAuthors() {
        $sql = 'SELECT * FROM authors';

        $statement = $this->connection->prepare($sql);
        $statement->execute();
        $result = $statement->get_result();

        // Fetch the data into a stdClass[] array.
        $rows = [];
        while ($row = $result->fetch_object()) {
            $rows[] = $row;
        }

        // Fill and return the authors collection.
        return $this->createAuthorsCollection($rows);
    }

    /**
     * Get an author by id.
     *
     * @param int $authorId Author id.
     * @return Author The author.
     */
    public function getAuthorById(int $authorId) {
        $sql = 'SELECT *
                FROM authors
                WHERE id = ?
                LIMIT 1';

        $statement = $this->connection->prepare($sql);
        $statement->bind_param('i', $authorId);
        $statement->execute();
        $result = $statement->get_result();

        // Fetch the data into a stdClass object.
        $row = $result->fetch_object();

        // Crete and return an Author object.
        return $this->createAuthor($row);
    }

    /**
     * Create an Author from the given stdClass object:
     *
     * - Create an Author object.
     * - Assign a property value to the Author object for each property of the given stdClass object.
     * - Return the Author object.
     *
     * @param stdClass $row The row object.
     * @return Author The author.
     */
    public function createAuthor(stdClass $row) {
        $author = new Author();

        $author
                ->setId($row->id)
                ->setFirstName($row->first_name)
                ->setLastName($row->last_name)
        ;

        return $author;
    }

    /**
     * Create an Author[] list from the given stdClass[] list:
     *
     * - Iterate through the given stdClass[] list.
     * - Create an Author object for each list item.
     * - Assign a property value to the Author object for each property of the given stdClass object.
     * - Push the Author object to the authors collection.
     * - Return the content of the collection.
     *
     * @param array $rows Rows list as a stdClass[] list.
     * @return Author[] The authors list as an Author[] list.
     */
    public function createAuthorsCollection(array $rows = []) {
        foreach ($rows as $row) {
            $this->authorsCollection[] = $this->createAuthor($row);
        }

        return $this->authorsCollection;
    }

}

index.php:

<?php

require 'connection.php';
require_once 'AuthorMapper.php';

// Create an author data mapper.
$authorMapper = new AuthorMapper($connection);

/*
 * ================================
 * Example 1: Get all authors.
 * ================================
 */

// Get all authors.
$authors = $authorMapper->getAllAuthors();

// Print the results.
echo '<b>Example 1: The whole authors list:</b>';
echo '<br/></br/>';
foreach ($authors as $author) {
    echo $author->getId() . ' - ' . $author->getName() . '<br/>';
}

echo '<br/><hr/><br/>';

/*
 * ================================
 * Example 2: Get an author by id.
 * ================================
 */

// Get an author by id.
$author = $authorMapper->getAuthorById(2);

// Print the results.
echo '<b>Example 2: One selected author:</b>';
echo '<br/><br/>';
echo $author->getId() . ' - ' . $author->getName();

如您所见,AuthorMapper查询数据库,并将表行提取到stdClass类型的对象的集合中。然后,将这些对象映射到类型为Author的相应对象,这些对象的属性将被打印或由某些方法(如getName()使用)以实现某些结果。

每个替代项的输出:

The output

使用的数据:

CREATE TABLE `authors` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `first_name` varchar(100) DEFAULT NULL,
  `last_name` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `authors` (`id`, `first_name`, `last_name`)
VALUES
    (1,'Johny','John'),
    (2,'Samantha','Sam'),
    (3,'Maria','Mar');

资源列表: