php - 如何从另一个函数中的另一个文件访问连接函数
问题描述
这里的问题是 viewauthor.php 将$conn
视为未定义的变量。它还给了我一个错误,该错误mysqli_query() expects parameter 1 to be mysqli, null given in
在该$results
行中说明。如何让 viewauthor.php 访问$conn
dbconnect.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;
}
}
?>
解决方案
发现问题:
- 请参阅
$con = new dbconn()
:要定义类的属性,请使用关键字public、protected或private、static、constant等之一,然后是普通的变量声明。请参阅属性。 - 请参阅
$con = new dbconn()
:您不能将对象创建为属性定义的一部分。属性值必须是常量表达式,而不是(例如)变量、属性或函数调用。请参阅属性和类常量。 - 请参阅
$results = mysqli_query($conn, $query);
:您为什么会收到错误“mysqli_query() 期望参数 1 为 mysqli,null given in ...”?因为您正在尝试引用$conn
,但它既没有定义为viewAuthor
方法定义中的参数-likeviewAuthor($conn) {...}
,也没有正确定义为类属性-如果是这样,您必须像这样引用它:$results = mysqli_query($this->conn, $query);
.
现在我将尝试给你两个正确的选择。但只有第二个是推荐的。我会尽量保持我的解释简单。请注意我的命名和编码约定,包括更改的表名、页面名称、require
连接页面的语句等。不要忘记connection.php
使用您的更改页面中的数据库凭据。
但是,首先,一些建议:
- 不要使用类连接到数据库。只需使用正确的连接代码创建一个包含文件(请参阅 参考资料
connection.php
)。 - 为需要访问数据库的每个类创建一个构造函数,并为要作为参数传递的连接对象定义一个参数。这个传递步骤称为依赖注入。
require
在require_once
包含connection.php
. _- 使用面向对象的 mysqli,而不是过程的。对于php.net上描述的每个 mysqli 过程函数,也有一个面向对象样式的函数。
- 重要提示:使用准备好的语句而不是直接使用
mysqli_query
. 也看到这个。 - 重要提示:阅读此内容和此内容以正确应用错误处理。例如优雅而安全地摆脱
die(...)
,mysqli_error()
等。 - 重要:实现一个自动加载器,或者更好的是,使用Composer库。也实现命名空间。阅读PSR-1、PSR-2、PSR-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');
资源清单:
推荐阅读
- javascript - 延迟加载网格:滚动一个大部分被溢出隐藏的大的空div:auto
- javascript - 在 Google 表格 App 脚本上使用 TextFinder 时返回表格名称
- android - 如何将列表数据从活动 A 发送到活动 B 并编辑活动 B 中的数据
- masstransit - 有没有办法修改 Masstransit 传输到 _error 队列的消息?
- visual-studio - 使用 Unity 构建后通过 USB 部署到 Hololens 1 时出错
- sql - 顶级命令在 SQL Server 中如何工作?
- flutter - \begin, \overline 等在 KaTex 颤振中不起作用
- python - SHAP使用隔离森林的基值和预测值很大
- vba - Access 中查找字段的数据类型是否应该与源表不同?
- visual-studio-2019 - 尝试使用 Entity Framework 6.4.4 添加新迁移时出错