首页 > 解决方案 > 如何从另一个函数中的另一个文件访问连接函数

问题描述

这里的问题是 viewauthor.php 将$conn视为未定义的变量。它还给了我一个错误,该错误mysqli_query() expects parameter 1 to be mysqli, null given in在该$results行中说明。如何让 viewauthor.php 访问$conndbconnect.php 文件中的?

这是 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;
    }
 }
 ?>

标签: php

解决方案


发现问题:

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

现在我将尝试给你两个正确的选择。但只有第二个是推荐的。我会尽量保持我的解释简单。请注意我的命名和编码约定,包括更改的表名、页面名称、require连接页面的语句等。不要忘记connection.php使用您的更改页面中的数据库凭据。

但是,首先,一些建议

  • 不要使用类连接到数据库。只需使用正确的连接代码创建一个包含文件(请参阅 参考资料connection.php)。
  • 为需要访问数据库的每个类创建一个构造函数,并为要作为参数传递的连接对象定义一个参数。这个传递步骤称为依赖注入
  • requirerequire_once包含connection.php. _
  • 使用面向对象的 mysqli,而不是过程的。对于php.net上描述的每个 mysqli 过程函数,也有一个面向对象样式的函数。
  • 重要提示:使用准备好的语句而不是直接使用mysqli_query. 也看到这个
  • 重要提示:阅读内容和内容以正确应用错误处理。例如优雅而安全地摆脱die(...),mysqli_error()等。
  • 重要:实现一个自动加载器,或者更好的是,使用Composer库。也实现命名空间。阅读PSR-1PSR-2PSR-4以及及时阅读PHP-FIG的其他建议。

备选方案 1:

在下面的代码中,很明显,为什么这个替代方案不是一个好的替代方案:

  • 一个类型的对象Author——它实际上应该是一个表行的表示——用于获取作者的集合。它们甚至被作为类型对象的集合获取stdClass。坏的。
  • 类型的对象Author负责查询数据库。实际上,为什么类型对象应该Author与数据库有关?坏的。

连接.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);

作者.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;
    }

}

索引.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视为一个实体,其唯一目的是保持作者的特征并按需操纵它们。这种类型的对象称为域对象,只负责业务逻辑。看到这个答案。因此,Author对象应该与数据库或任何其他持久层(会话、文件系统等)无关。它实际上应该完全不知道获取其属性的位置和方式。

因此,查询数据库、获取作者特征(例如表中特定行的字段值authors)并将它们分配给Author对象的责任应该交给所谓的数据映射器

因此,您的案例中的代码如下所示:

连接.php:

和上面一样。

作者.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;
    }

}

索引.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();

如您所见, anAuthorMapper查询数据库并将表行提取到 type 对象的集合中stdClass。然后它将这些对象映射到 type 的相应对象Author,其属性被打印出来,或者被某些方法(如getName())使用以达到某些结果。

每个备选方案的输出:

输出

使用数据:

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');

资源清单:


推荐阅读