PHP Тип вызываемая функция подсказки - PullRequest
1 голос
/ 06 августа 2020

Хорошо, поэтому у меня есть этот метод класса, определенный для выполнения обратного вызова, и я напечатал намека на его как вызываемый в соответствии с документацией по подсказкам типов.

protected function AddTransformData(array $definition,array $where,callable $callback){
    $this->transforms[]=[$definition,$where,$callback];
}

Вот пример того, где я мог бы позвонить эта функция. Использование синтаксиса массива для передачи метода и объекта в качестве обратного вызова.

public function __construct(PostalZoneMapping $pzm){
    $this->pzm=$pzm;
    $this->AddTransformData(Countries::region,['filter'],[$this,'TransformId']);
    $this->AddTransformData(PostalZones::id,['filter'],[$this,'TransformId']);
    $this->ReceiveData();
}

Это вызывает ошибку, как показано на рисунке ниже, с жалобой на то, что аргумент 3 не вызывается, а является массивом. Логически, я думаю, в этом есть смысл, так как это массив, но это массив вызываемой функции - наверняка он должен определить, что это обратный вызов?

Это PHP причуда или я делаю что-то не так ?

Исключение из передачи вызываемого массива в качестве вызываемого параметра

Ответы [ 3 ]

1 голос
/ 06 августа 2020

Похоже, что TransformId не является методом этого класса. Может быть, это опечатка, может быть, это свойство, а не метод.

Чтобы массив был действительным обратным вызовом, он должен быть: A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1.

Это работает:

class A {
  function __construct() {
    $this->asd2([$this, 'asd']);
  }
  private function asd() {}

  public function asd2(callable $c) {}
}

$a = new A();

Это не:

class A {
  function __construct() {
    $this->asd2([$this, 'somethingElse']);
  }
  private function asd() {}

  public function asd2(callable $c) {}
}

Fatal error: Uncaught TypeError: Argument 1 passed to A::asd2() must be callable, array given, called in

Если я ошибаюсь - вставьте весь код класса, включая TransformId метод.

1 голос
/ 06 августа 2020
public function __construct(PostalZoneMapping $pzm){
    $this->pzm=$pzm;
    $method = 'TransformId';
    $callable = fn() => $this->$method();
    $this->AddTransformData(Countries::region,['filter'], $callable);
    $this->AddTransformData(PostalZones::id,['filter'], $callable);
    $this->ReceiveData();
}

если у вас версия PHP ниже 7.4, то вместо этого:

$callable = fn() => $this->$method();

сделайте следующее:

$callable = function() use ($method) { $this->$method() };

Вы также можете получить аргументы:

$callable = fn($param) => $this->$method($param);

или

$callable = function($param) use ($method) { $this->$method($param)};
0 голосов
/ 06 августа 2020

Я создаю тестовый код для воспроизведения ошибки, заметив, что объявил обратный вызов как частный! Этот код не будет работать, но будет работать, если вы измените метод TransformId на protected или publi c.

<?php

abstract class CommonDataInterface{
    private $transforms=[];
    /**
     * Adds a callback that transform data 
     *
     * @param array $definition Definition, where, if matches, callback is called.
     * @param array $where Where to transform data, array values one or more of 'set','insert' or'filter'
     * @param callable $callback Function that takes value as parameter, and returns transformed value.
     * @return void
     */
    protected function AddTransformData(array $definition,array $where,callable $callback){
        $this->transforms[]=[$definition,$where,$callback];
    }
}


class Api_PostalZoneMapping extends CommonDataInterface{
    private $pzm;

    public function __construct($pzm){
        $this->pzm=$pzm;
        $this->AddTransformData(['blah'],['filter'],[$this,'TransformId']);
        $this->AddTransformData(['blah2'],['filter'],[$this,'TransformId']);
        //$this->ReceiveData();
    }

    private function TransformId($data){
        if($data==-1)
            return null;
        return $data;
    }
}

$p=new Api_PostalZoneMapping('not relevant for test');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...