我有一个用PHP构建的上传类,它具有各种功能,用于检查文件并确保它符合正确的规范。但是,我有一个功能,剥离文件的名称,并给它一个新的名称,这是一个数字。在这个函数中,我包括我的连接包括开始与DB的连接。为了防止给两个文件使用相同的名称,我的数据库中有一个表,其中包含当前计数,该表指的是最后一个图像编号。当我上传图像时,它从数据库中提取计数并向其中添加一个并将该数字存储为图像的名称。然后我再次通过查询DB来更新表的新计数。这工作正常,但是当我在另一个函数中查询数据库以输入文件的路径时,它告诉我没有声明我的连接变量。我已经发布了我的连接代码,包括下面以及我调用的两个函数。如果我没有在正确的位置开始连接,我很好奇。我已经尝试释放结果并在调用函数后关闭连接,然后在另一个函数中再次打开连接以提交文件路径,但这似乎也不起作用。我知道他们是关于在任何时候打开一个连接的规则,但我可以在该连接中多次查询数据库。
连接包括
// Create a database connection
$dbhost = "localhost";
$dbuser = "user";
$dbpass = "password";
$dbname = "new_db";
$connection = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);
// Test if connection occured.
if(mysqli_connect_errno()) {
die("Database connection failed: " .
mysqli_connect_error() .
" (" . mysqli_connect_errno() . ")"
);
}
第一个功能
//replaces the filename with an incremented number
public function trim_filename() {
require_once( 'includes/connection.php' );
$query = "SELECT * FROM image_count ";
$result = mysqli_query($connection, $query);
if (!$result) {
die("Database query failed. ");
}
$row = mysqli_fetch_assoc($result);
$count = 1 + $row["name"];
mysqli_free_result($result);
$query = "UPDATE image_count SET name = '{$count}' WHERE count = 1";
$result = mysqli_query($connection, $query);
if (!$result) {
die("Database query failed. ");
}
$file = $_FILES['image']['name'];
$file = explode(".", $file);
$file = end($file);
$file = $count . "." . $file;
$_FILES['image']['name'] = $file;
$this->final_check();
mysqli_free_result($result);
mysqli_close($connection);
}
第二功能
public function database_query($in_path) {
$query = "INSERT INTO course (";
$query .= " course_name ";
$query .= ") VALUES (";
$query .= " '{$in_path}'";
$query .= ")";
$result = mysqli_query($connection, $query);
if (!$result) {
die("Database query failed. ");
}
mysqli_free_result($result);
mysqli_close($connection);
}
答案 0 :(得分:0)
这是一个常见问题,尤其是如果您之前有使用旧mysql_query()
API的经验,该API依赖于从全局状态中提取的连接资源。您需要在适当的范围内使用$connection
才能在函数中使用它。
处理此问题的最佳方法是 not 来完成类中的require_once()
以建立连接。相反,在类之外执行该操作,并将生成的$connection
变量传递给类“__construct()
方法。然后将其存储在类中的属性中,您可以将其用作$this->connection
。这称为依赖注入。
class ThisClass
{
// A public property for the connection
protected $connection;
// Modify your __construct() to accept the connection
public function __construct(/* existing params... , */ mysqli $connection)
{
// Whatever your constructor already does...
// Store the connection in a property
$this->connection = $connection;
}
// Then modify those two methods to use $this->connection
public function trim_filename() {
$query = "SELECT * FROM image_count ";
// Use $this->connection
$result = mysqli_query($this->connection, $query);
if (!$result) {
die("Database query failed. ");
}
// SNIP....
// Don't free/close the connection!
}
// Then modify those two methods to use $this->connection
public function database_query($in_path) {
$query = "INSERT INTO course (";
// SNIP...
// Use $this->connection
$result = mysqli_query($this->connection, $query);
if (!$result) {
die("Database query failed. ");
}
// Don't free/close the connection!
}
}
现在,使用具有连接依赖关系的类:
// Done outside the class, defines $connection
require_once( 'includes/connection.php' );
// Then when you use the class
// give it the $connection as a parameter
$object = new ThisClass($connection);
$object->trim_filename();
没有关于在任何时候打开一个连接的规则,但是需要不止一个,这种情况很少见。
非理想的替代方案:如果确实由于某种原因不希望将连接存储在类属性中,您也可以修改这两种方法以接受$connection
像
// Add a param to the functions that need it.
public function trim_filename($connection) {
// use $connection->query(...);
}
// Call outside the class as:
$object->trim_filename($connection);
你仍然在课堂外做require_once()
。但是将它作为依赖项注入构造函数更简洁,并为您提供了一个简单的路径来扩展需要访问数据库连接的类中的更多方法。
在需要它的方法中使用$connection
关键字访问global
变量是最不受欢迎的方法,特别是如果您继续在其中一个内部建立它类功能。通过面向对象的原则,建立数据库连接不应该是类的责任。相反,如果类需要一个,它应该从外部传递给对象。
答案 1 :(得分:-1)
你能试试“全球联系”吗?在database_query函数中?你也不应该关闭函数中的连接
public function database_query($in_path) {
global $connection;
$query = "INSERT INTO course (";
$query .= " course_name ";
$query .= ") VALUES (";
$query .= " '{$in_path}'";
$query .= ")";
$result = mysqli_query($connection, $query);
if (!$result) {
die("Database query failed. ");
}
mysqli_free_result($result);
mysqli_close($connection);
}
答案 2 :(得分:-1)
处理这类情况的最佳方法是 将所有功能放在一个文件中,例如(example:function.php),然后在function.php.Use全局变量的顶部包含你的connection.php文件,以获得每个函数中的连接对象
Connection.php文件
// Create a database connection
$dbhost = "localhost";
$dbuser = "user";
$dbpass = "password";
$dbname = "new_db";
$connection = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);
// Test if connection occured.
if(mysqli_connect_errno()) {
die("Database connection failed: " .
mysqli_connect_error() .
" (" . mysqli_connect_errno() . ")"
);
}
function.php文件
//inculing connnection.php file
require_once( 'includes/connection.php' );
//first funtion
public function trim_filename() {
globel $connection;
// code here
}
//second funtion
public database_query($in_path) {
globel $connection;
// code here
}