你不能在一个PHP类中放入两个具有唯一参数签名的__construct函数。我想这样做:
class Student
{
protected $id;
protected $name;
// etc.
public function __construct($id){
$this->id = $id;
// other members are still uninitialized
}
public function __construct($row_from_database){
$this->id = $row_from_database->id;
$this->name = $row_from_database->name;
// etc.
}
}
PHP中最好的方法是什么?
我知道我在这方面非常晚,但我提出了一个相当灵活的模式,应该允许一些真正有趣和通用的实现。
像往常一样设置类,使用您喜欢的任何变量。
class MyClass{
protected $myVar1;
protected $myVar2;
public function __construct($obj = null){
if($obj){
foreach (((object)$obj) as $key => $value) {
if(isset($value) && in_array($key, array_keys(get_object_vars($this)))){
$this->$key = $value;
}
}
}
}
}
When you make your object just pass an associative array with the keys of the array the same as the names of your vars, like so...
$sample_variable = new MyClass([
'myVar2'=>123,
'i_dont_want_this_one'=> 'This won\'t make it into the class'
]);
print_r($sample_variable);
The print_r($sample_variable); after this instantiation yields the following:
MyClass Object ( [myVar1:protected] => [myVar2:protected] => 123 )
Because we've initialize $group to null in our __construct(...), it is also valid to pass nothing whatsoever into the constructor as well, like so...
$sample_variable = new MyClass();
print_r($sample_variable);
Now the output is exactly as expected:
MyClass Object ( [myVar1:protected] => [myVar2:protected] => )
The reason I wrote this was so that I could directly pass the output of json_decode(...) to my constructor, and not worry about it too much.
This was executed in PHP 7.1. Enjoy!
为了回应Kris的最佳答案(顺便说一句,他帮助我设计了自己的课程),这里有一个修改过的版本,供那些可能会觉得有用的人使用。包括用于从任何列中进行选择和从数组中转储对象数据的方法。干杯!
public function __construct() {
$this -> id = 0;
//...
}
public static function Exists($id) {
if (!$id) return false;
$id = (int)$id;
if ($id <= 0) return false;
$mysqli = Mysql::Connect();
if (mysqli_num_rows(mysqli_query($mysqli, "SELECT id FROM users WHERE id = " . $id)) == 1) return true;
return false;
}
public static function FromId($id) {
$u = new self();
if (!$u -> FillFromColumn("id", $id)) return false;
return $u;
}
public static function FromColumn($column, $value) {
$u = new self();
if (!$u -> FillFromColumn($column, $value)) return false;
return $u;
}
public static function FromArray($row = array()) {
if (!is_array($row) || $row == array()) return false;
$u = new self();
$u -> FillFromArray($row);
return $u;
}
protected function FillFromColumn($column, $value) {
$mysqli = Mysql::Connect();
//Assuming we're only allowed to specified EXISTENT columns
$result = mysqli_query($mysqli, "SELECT * FROM users WHERE " . $column . " = '" . $value . "'");
$count = mysqli_num_rows($result);
if ($count == 0) return false;
$row = mysqli_fetch_assoc($result);
$this -> FillFromArray($row);
}
protected function FillFromArray(array $row) {
foreach($row as $i => $v) {
if (isset($this -> $i)) {
$this -> $i = $v;
}
}
}
public function ToArray() {
$m = array();
foreach ($this as $i => $v) {
$m[$i] = $v;
}
return $m;
}
public function Dump() {
print_r("<PRE>");
print_r($this -> ToArray());
print_r("</PRE>");
}
正如这里已经展示的,在PHP中有许多方法来声明多个构造函数,但是没有一种方法是正确的(因为PHP技术上不允许这样做)。
但这并不能阻止我们破解这个功能……
下面是另一个例子:
<?php
class myClass {
public function __construct() {
$get_arguments = func_get_args();
$number_of_arguments = func_num_args();
if (method_exists($this, $method_name = '__construct'.$number_of_arguments)) {
call_user_func_array(array($this, $method_name), $get_arguments);
}
}
public function __construct1($argument1) {
echo 'constructor with 1 parameter ' . $argument1 . "\n";
}
public function __construct2($argument1, $argument2) {
echo 'constructor with 2 parameter ' . $argument1 . ' ' . $argument2 . "\n";
}
public function __construct3($argument1, $argument2, $argument3) {
echo 'constructor with 3 parameter ' . $argument1 . ' ' . $argument2 . ' ' . $argument3 . "\n";
}
}
$object1 = new myClass('BUET');
$object2 = new myClass('BUET', 'is');
$object3 = new myClass('BUET', 'is', 'Best.');
使用和理解多个构造函数的最简单方法:
希望这能有所帮助。:)
我知道我在这方面非常晚,但我提出了一个相当灵活的模式,应该允许一些真正有趣和通用的实现。
像往常一样设置类,使用您喜欢的任何变量。
class MyClass{
protected $myVar1;
protected $myVar2;
public function __construct($obj = null){
if($obj){
foreach (((object)$obj) as $key => $value) {
if(isset($value) && in_array($key, array_keys(get_object_vars($this)))){
$this->$key = $value;
}
}
}
}
}
When you make your object just pass an associative array with the keys of the array the same as the names of your vars, like so...
$sample_variable = new MyClass([
'myVar2'=>123,
'i_dont_want_this_one'=> 'This won\'t make it into the class'
]);
print_r($sample_variable);
The print_r($sample_variable); after this instantiation yields the following:
MyClass Object ( [myVar1:protected] => [myVar2:protected] => 123 )
Because we've initialize $group to null in our __construct(...), it is also valid to pass nothing whatsoever into the constructor as well, like so...
$sample_variable = new MyClass();
print_r($sample_variable);
Now the output is exactly as expected:
MyClass Object ( [myVar1:protected] => [myVar2:protected] => )
The reason I wrote this was so that I could directly pass the output of json_decode(...) to my constructor, and not worry about it too much.
This was executed in PHP 7.1. Enjoy!