将方法作为构造函数参数传递

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?.