调用 class 方法的 public 构造函数与调用另一个 class 方法的 class 方法有什么区别?
What is the difference between a public constructor which calls a class method and a class method that calls another class method?
我对 OO 编程有点陌生,无法理解为什么一种机制有效而另一种机制无效。
我创建了一个简单的 class,用于 return 一个 MySQL 数据库句柄。我尝试直接从构造函数 returning 句柄失败。但是在创建实例后,从 class 方法或 class(?) 方法成功。这是 class 定义和示例脚本
<?php
class HMMDatabaseHandle {
private static $configfile = "config.json";
// uncomment for test 1
// public function __construct () {
// return self::get_handle_admin();
// }
public static function create() {
return self::get_handle_admin();
}
private static function get_handle_admin() {
$config = json_decode(file_get_contents(self::$configfile));
$dbhost = $config->database->dbhost;
$dbname = $config->database->dbname;
$dbuser = $config->database->dbuser;
$dbpass = $config->database->dbpass;
try {
return new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
}
catch(PDOException $e) {
echo $e->getMessage();
}
}
}
?>
这是我正在使用的测试脚本:
<?php
require_once 'HMMDatabaseHandle.php';
// Test 1 - fails (uncomment constructor func) at call to prepare() with:
// PHP Fatal error: Call to undefined method HMMDatabaseHandle::prepare()
//$dbh = new HMMDatabaseHandle();
// Test 2 - works when class creates default constructor
// i.e. no explicit __construct() func
// Fetching data from executed query is fine
//$db = new HMMDatabaseHandle();
//$dbh = $db->create();
// Works using static class methods rather than instance
$dbh = HMMDatabaseHandle::create();
$sth = $dbh->prepare('select data_title,track_id from master');
$sth->execute();
while($row = $sth->fetch(PDO::FETCH_ASSOC)) {
...
}
我的问题是:
为什么我不能直接从构造函数 return 句柄,因为它看起来与直接调用 class 方法非常相似?为什么构造函数调用 class 方法或我的脚本调用它很重要?
如果我用 PHP 的默认构造函数创建一个实例,我真的是在用 $db->create() 调用 class 方法吗?
我似乎在这里遗漏了一些基本概念。提前致谢!
您不能 return 在该上下文中构造函数的句柄,因为那样会违反 new
定义的行为。 new SomeClass();
只会 return class 的一个实例,而不管在构造函数中调用了哪些其他方法。
__construct()
是无效方法。它不是打算到return任何东西1。这并不意味着其中的其他代码不会被执行,只是您的 return
在创建新对象的上下文中被忽略了。这是有道理的,因为构造函数的主要目的是提供一种将依赖项传递给对象的方法。有时它用于对象的附加 initialization/setup,但许多人认为除了将给定参数分配给对象的属性外,它不应该做任何其他工作。无论哪种方式,都不需要 return 任何东西。
1 你 可以 实际上显式地调用 __construct()
方法 在 你之后创建对象,然后它将像普通方法一样运行,您的 return
将起作用。
$db = new HMMDatabaseHandle();
$dbh = $db->__construct();
var_dump($dbh); // PDO Object
虽然这不是一件正常的事情,但我想不出有什么用处或需要它的情况。我只是想指出这是可能的。
Why can't I return the handle directly from a constructor when it
seems so similar to calling the class method directly?
如果你能做到这一点,那么你就不会有 HMMDatabaseHandle
的实例;你会有一个 PDO
的实例。您将如何访问 HMMDatabaseHandle
提供的任何其他方法?
虽然我完全同意@Don't Panic 的回答,但我还需要指出您混合了静态方法和实例方法。
作为一般经验法则,如果您希望能够在不首先实例化对象的情况下调用方法,请使用 static
关键字。如果你想实际创建和使用一个对象,那么你可以像这样定义你class并使用$this->
(或者$object->
如果在class) 而不是 ::
来访问 实例 属性和方法。
<?php
class HMMDatabaseHandle
{
private $configfile = "config.json";
public function __construct()
{
// You're not initializing anything in here, so this constructor is optional.
}
public function create()
{
return $this->get_handle_admin();
}
private function get_handle_admin()
{
$config = json_decode(file_get_contents($this->configfile));
$dbhost = $config->database->dbhost;
$dbname = $config->database->dbname;
$dbuser = $config->database->dbuser;
$dbpass = $config->database->dbpass;
try {
return new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
}
catch (PDOException $e) {
echo $e->getMessage();
}
}
}
要实际执行此操作,您现在需要实例化新的 class。
$dbManager = new HMMDatabaseHandle();
$handle = $dbManager->create();
最后,您可以使用一个技巧使您的构造函数 可链接 。只需将其括在括号中即可。
$handle = (new HMMDatabaseHandle())->create();
我对 OO 编程有点陌生,无法理解为什么一种机制有效而另一种机制无效。
我创建了一个简单的 class,用于 return 一个 MySQL 数据库句柄。我尝试直接从构造函数 returning 句柄失败。但是在创建实例后,从 class 方法或 class(?) 方法成功。这是 class 定义和示例脚本
<?php
class HMMDatabaseHandle {
private static $configfile = "config.json";
// uncomment for test 1
// public function __construct () {
// return self::get_handle_admin();
// }
public static function create() {
return self::get_handle_admin();
}
private static function get_handle_admin() {
$config = json_decode(file_get_contents(self::$configfile));
$dbhost = $config->database->dbhost;
$dbname = $config->database->dbname;
$dbuser = $config->database->dbuser;
$dbpass = $config->database->dbpass;
try {
return new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
}
catch(PDOException $e) {
echo $e->getMessage();
}
}
}
?>
这是我正在使用的测试脚本:
<?php
require_once 'HMMDatabaseHandle.php';
// Test 1 - fails (uncomment constructor func) at call to prepare() with:
// PHP Fatal error: Call to undefined method HMMDatabaseHandle::prepare()
//$dbh = new HMMDatabaseHandle();
// Test 2 - works when class creates default constructor
// i.e. no explicit __construct() func
// Fetching data from executed query is fine
//$db = new HMMDatabaseHandle();
//$dbh = $db->create();
// Works using static class methods rather than instance
$dbh = HMMDatabaseHandle::create();
$sth = $dbh->prepare('select data_title,track_id from master');
$sth->execute();
while($row = $sth->fetch(PDO::FETCH_ASSOC)) {
...
}
我的问题是:
为什么我不能直接从构造函数 return 句柄,因为它看起来与直接调用 class 方法非常相似?为什么构造函数调用 class 方法或我的脚本调用它很重要?
如果我用 PHP 的默认构造函数创建一个实例,我真的是在用 $db->create() 调用 class 方法吗?
我似乎在这里遗漏了一些基本概念。提前致谢!
您不能 return 在该上下文中构造函数的句柄,因为那样会违反 new
定义的行为。 new SomeClass();
只会 return class 的一个实例,而不管在构造函数中调用了哪些其他方法。
__construct()
是无效方法。它不是打算到return任何东西1。这并不意味着其中的其他代码不会被执行,只是您的 return
在创建新对象的上下文中被忽略了。这是有道理的,因为构造函数的主要目的是提供一种将依赖项传递给对象的方法。有时它用于对象的附加 initialization/setup,但许多人认为除了将给定参数分配给对象的属性外,它不应该做任何其他工作。无论哪种方式,都不需要 return 任何东西。
1 你 可以 实际上显式地调用 __construct()
方法 在 你之后创建对象,然后它将像普通方法一样运行,您的 return
将起作用。
$db = new HMMDatabaseHandle();
$dbh = $db->__construct();
var_dump($dbh); // PDO Object
虽然这不是一件正常的事情,但我想不出有什么用处或需要它的情况。我只是想指出这是可能的。
Why can't I return the handle directly from a constructor when it seems so similar to calling the class method directly?
如果你能做到这一点,那么你就不会有 HMMDatabaseHandle
的实例;你会有一个 PDO
的实例。您将如何访问 HMMDatabaseHandle
提供的任何其他方法?
虽然我完全同意@Don't Panic 的回答,但我还需要指出您混合了静态方法和实例方法。
作为一般经验法则,如果您希望能够在不首先实例化对象的情况下调用方法,请使用 static
关键字。如果你想实际创建和使用一个对象,那么你可以像这样定义你class并使用$this->
(或者$object->
如果在class) 而不是 ::
来访问 实例 属性和方法。
<?php
class HMMDatabaseHandle
{
private $configfile = "config.json";
public function __construct()
{
// You're not initializing anything in here, so this constructor is optional.
}
public function create()
{
return $this->get_handle_admin();
}
private function get_handle_admin()
{
$config = json_decode(file_get_contents($this->configfile));
$dbhost = $config->database->dbhost;
$dbname = $config->database->dbname;
$dbuser = $config->database->dbuser;
$dbpass = $config->database->dbpass;
try {
return new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
}
catch (PDOException $e) {
echo $e->getMessage();
}
}
}
要实际执行此操作,您现在需要实例化新的 class。
$dbManager = new HMMDatabaseHandle();
$handle = $dbManager->create();
最后,您可以使用一个技巧使您的构造函数 可链接 。只需将其括在括号中即可。
$handle = (new HMMDatabaseHandle())->create();