Устранение неоднозначности сигнатур методов для PHP "перегрузка" - PullRequest
0 голосов
/ 31 августа 2011

У меня есть метод, который поддерживает сложную «перегрузку», используя func_get_args для определения сигнатуры метода. Однако в некоторых ситуациях типы аргументов слишком неоднозначны, чтобы проводить различие.

designGarment('my shirt', SIZES::XXL, FABRICS::COTTON);
designGarment('my dress', FABRICS::SILK, ATTIRES::PARTY);

В приведенном выше примере обе сигнатуры метода разрешаются в STRING, INT, INT, поскольку SIZES, FABRICS и ATTIRES являются классами с целочисленными константами, определенными для их соответствующих свойств. Я хочу иметь возможность отличить подпись (STRING, SIZES, FABRICS) от подписи (STRING, FABRICS, ATTIRES). Возможно ли это в PHP?

Ответы [ 2 ]

2 голосов
/ 31 августа 2011

Используйте объекты вместо угадывания аргументов:

class Garment
{
  var $name;
  var $size;
  var $fabric;
  var $attires;
}

$Garment = new Garment(...);
function designGarment($Garment);

Или используйте массив пар ключ / значение для явного указания аргументов и их значений:

designGarment(array(
  'name' => 'my dress',
  'fabric' => FABRICS::SILK,
  'attires' => ATTIRES::PARTY
));
0 голосов
/ 01 сентября 2011

Рядом с ответом @Brad Christie есть еще несколько:

  1. Рекомендуется: использовать аргументы в постоянном порядке и ноль в качестве значений по умолчанию для пропущенных

    function designGarment($name, $size = null, $fabric = null, $attire = null){
        if(!is_null($size)){ }
        //etc
    }
    
    designGarment('my dress', NULL, FABRICS::SILK, ATTIRES::PARTY);
    
  2. Использование объекта для хранения необязательных аргументов

    $options = new stdClass;
    $options->size = SIZES::XXL; 
    function designGarment($name, $options = null){
    
    }
    
  3. Создание отдельного объекта для каждого типа свойства

    function designGarment(){
        foreach(func_get_args() as $arg){
            if($arg instanceof Size){ }
        }
    }
    designGarment($name, new Size('XXL'), new Fabric('WOOL'));
    
  4. Похожиевыше, но иметь отдельный объект для каждого типа и значения свойства (не рекомендуется, но я видел несколько случаев, использующих это)

    class Size{ public $size; }
    class SizeXXL extends Size{
        public function __construct(){ $this->size = SIZES::XXL; } 
    }
    designGarment($name, new SizeXXL);
    
...