将方法作为构造函数参数传递
Pass method as constructor parameter
我正在尝试为 API 编写 class,我需要我的构造函数使用一些方法作为参数(因为我将从 csv 中获取数据)。我正在用这个做一些测试:
class API {
public $a;
public $b;
function __construct(){
$this->a = setA($a);
$this->b = setB($b);
}
function setA($a){
$a = "X";
}
function setB($b){
$b = "Y";
}
}
但它不起作用。这甚至可能或正确吗?
编辑: 根据用户 Halcyon 的要求。
最初的设计是基于各种相互影响的功能。这不是最好的,因为数据被一遍又一遍地获取,而不是只从一个地方读取。
csv 和 json 的方法是:
function getJsonData(){
$stream = fopen('php://input', 'rb');
$json = stream_get_contents($stream);
fclose($stream);
$order_json_data = json_decode($json, true);
return $order_json_data;
}
function getProductsTable($csvFile = '', $delimiter = ','){
if (!file_exists($csvFile) || !is_readable($csvFile))
echo 'File not here';
$header = NULL;
$data = array();
if (($handle = fopen($csvFile, 'r')) !== FALSE){
while (($row = fgetcsv($handle, 100, $delimiter)) !== FALSE){
if (!$header)
$header = $row;
else if($row[0] != ''){
$row = array_merge(array_slice($row,0,2), array_filter(array_slice($row, 2)));
$sku = $row[0];
$data[$sku]['productCode'] = $row[1];
$data[$sku]['Description'] = $row[2];
}
}
fclose($handle);
}
array_change_key_case($data, CASE_LOWER);
return $data;
}
编辑:包括我正在测试对象的索引文件。
<?php
require_once 'helpers/API.php';
if (in_array($_GET['action'],array('insertOrder','updateOrder'))){
$api = new API();
file_put_contents('debug/debug_info.txt', "Object response: {$api->a}, {$api->b}", FILE_APPEND | LOCK_EX);
}
您的代码有误:
class API {
public $a;
public $b;
function __construct($a=null, $b=null){
$this->a = $a;
$this->b = $b;
}
function setA($a){
$this->a = $a;
}
function setB($b){
$this->b = $b;
}
}
还引用对象方法并避免在函数范围内使用未声明的变量。
$api = new Api("test", "another value" );
我不明白为什么需要它,但你是用这种方式创建可调用的:
function __construct(){
$this->a = [$this, 'setA'];
$this->b = [$this, 'setB'];
}
现在,您可以使用
$propertyWithCallable = $object->a;
$propertyWithCallable();
代码有些问题。这里有几个例子来展示不同的方法:
-例1
class Foo {
public $a;
public $b;
function __construct(){
$this->setA();
$this->setB();
}
function setA(){
$this->a = "X";
}
function setB(){
$this->b = "Y";
}
}
-例2
class Foo {
public $a;
public $b;
function __construct(){
$this->a = $this->setA();
$this->b = $this->setB();
}
function setA(){
return "X";
}
function setB(){
return "Y";
}
}
请注意,您的代码更像是第二个示例,但它不起作用,因为该函数未返回任何内容(并且缺少 $this
)。
我不知道 $a
和 $b
是什么,或者如果您想从 class 中设置值(如果它们是常量或类似的东西),但我想提请您注意第二个示例的一个重要方面 - 特别是如果您真的在设计 API。在 OOP 中,我们通常有 getter 和 setters。而且基本都是我们封装我们的class的时候用到的。这是一个封装的示例 class:
class Bar{
private $a;
public function getA(){ return $this->a; }
public function setA($a){ $this->a = $a; }
}
请注意 $a
是私有的,因此我们无法直接从 class 访问它。我们有使用这些方法。这样我们就可以控制对该属性的访问,进行一些验证等。(如果设计良好)这使我们有机会进一步更改值 get/set 的实现方式,而无需查找它们的出现在整个项目中。如果将来您决定 $a
只能有数字,只需更改 setter.
这真的取决于 $a
是什么。您还可以使用 __construct
来初始化此变量。有许多不同的方法可以做同样的事情。不管怎样,看看Why use getters and setters?.
我正在尝试为 API 编写 class,我需要我的构造函数使用一些方法作为参数(因为我将从 csv 中获取数据)。我正在用这个做一些测试:
class API {
public $a;
public $b;
function __construct(){
$this->a = setA($a);
$this->b = setB($b);
}
function setA($a){
$a = "X";
}
function setB($b){
$b = "Y";
}
}
但它不起作用。这甚至可能或正确吗?
编辑: 根据用户 Halcyon 的要求。
最初的设计是基于各种相互影响的功能。这不是最好的,因为数据被一遍又一遍地获取,而不是只从一个地方读取。
csv 和 json 的方法是:
function getJsonData(){
$stream = fopen('php://input', 'rb');
$json = stream_get_contents($stream);
fclose($stream);
$order_json_data = json_decode($json, true);
return $order_json_data;
}
function getProductsTable($csvFile = '', $delimiter = ','){
if (!file_exists($csvFile) || !is_readable($csvFile))
echo 'File not here';
$header = NULL;
$data = array();
if (($handle = fopen($csvFile, 'r')) !== FALSE){
while (($row = fgetcsv($handle, 100, $delimiter)) !== FALSE){
if (!$header)
$header = $row;
else if($row[0] != ''){
$row = array_merge(array_slice($row,0,2), array_filter(array_slice($row, 2)));
$sku = $row[0];
$data[$sku]['productCode'] = $row[1];
$data[$sku]['Description'] = $row[2];
}
}
fclose($handle);
}
array_change_key_case($data, CASE_LOWER);
return $data;
}
编辑:包括我正在测试对象的索引文件。
<?php
require_once 'helpers/API.php';
if (in_array($_GET['action'],array('insertOrder','updateOrder'))){
$api = new API();
file_put_contents('debug/debug_info.txt', "Object response: {$api->a}, {$api->b}", FILE_APPEND | LOCK_EX);
}
您的代码有误:
class API {
public $a;
public $b;
function __construct($a=null, $b=null){
$this->a = $a;
$this->b = $b;
}
function setA($a){
$this->a = $a;
}
function setB($b){
$this->b = $b;
}
}
还引用对象方法并避免在函数范围内使用未声明的变量。
$api = new Api("test", "another value" );
我不明白为什么需要它,但你是用这种方式创建可调用的:
function __construct(){
$this->a = [$this, 'setA'];
$this->b = [$this, 'setB'];
}
现在,您可以使用
$propertyWithCallable = $object->a;
$propertyWithCallable();
代码有些问题。这里有几个例子来展示不同的方法:
-例1
class Foo {
public $a;
public $b;
function __construct(){
$this->setA();
$this->setB();
}
function setA(){
$this->a = "X";
}
function setB(){
$this->b = "Y";
}
}
-例2
class Foo {
public $a;
public $b;
function __construct(){
$this->a = $this->setA();
$this->b = $this->setB();
}
function setA(){
return "X";
}
function setB(){
return "Y";
}
}
请注意,您的代码更像是第二个示例,但它不起作用,因为该函数未返回任何内容(并且缺少 $this
)。
我不知道 $a
和 $b
是什么,或者如果您想从 class 中设置值(如果它们是常量或类似的东西),但我想提请您注意第二个示例的一个重要方面 - 特别是如果您真的在设计 API。在 OOP 中,我们通常有 getter 和 setters。而且基本都是我们封装我们的class的时候用到的。这是一个封装的示例 class:
class Bar{
private $a;
public function getA(){ return $this->a; }
public function setA($a){ $this->a = $a; }
}
请注意 $a
是私有的,因此我们无法直接从 class 访问它。我们有使用这些方法。这样我们就可以控制对该属性的访问,进行一些验证等。(如果设计良好)这使我们有机会进一步更改值 get/set 的实现方式,而无需查找它们的出现在整个项目中。如果将来您决定 $a
只能有数字,只需更改 setter.
这真的取决于 $a
是什么。您还可以使用 __construct
来初始化此变量。有许多不同的方法可以做同样的事情。不管怎样,看看Why use getters and setters?.