Реализация Ruby-подобных массивов в PHP - PullRequest
1 голос
/ 15 мая 2009

Я программирую на PHP чаще всего, а на Ruby иногда мне нужно найти способ реализовать эти "аргументы хеша" в моих функциях PHP (как, скажем, помощник выбора HTML)

draw_select :name => :id, :onclick => 'alert(this.value)'

Проблема в PHP заключается в том, что мне нужно определить порядок аргументов для реализации многих возможных атрибутов.

Я думал просто определить 1 строковый аргумент и использовать json_decode (), чтобы я мог передавать аргументы следующим образом:

draw_select("'name': 'id', 'onclick': 'alert(this.value)' ")

определение будет следующим:

function draw_select($string) {
// use json_decode here and pass them as variables
}

Знаете ли вы более разумный способ сделать это ... или вы думаете, что попытка сделать это в PHP на самом деле имеет какой-то смысл?

Отредактировано, чтобы добавить: я ищу «альтернативную» альтернативу, чтобы просто передать массив signle как аргумент, подобный функции (array (...))

Ответы [ 6 ]

5 голосов
/ 15 мая 2009

Почему бы не передать вместо этого массив?

draw_select(array(
  'name'=> 'id', 
  'onclick'=> 'alert(this.value)'
));
3 голосов
/ 15 мая 2009

PHP определенно не хватает сахара в этом аспекте. Я также много делаю на Python и очень скучаю по именованным аргументам при использовании PHP. В PHP, однако, всякий раз, когда у меня есть функция, которая должна принимать множество параметров, я просто принимаю один или два обязательных / важных аргумента и массив для остальных:

function draw_select($name, $options = array(), $html_options = array()) {

}

Именно так библиотеки, такие как CodeIgniter и CakePHP, обрабатывают один и тот же сценарий <select>.

Лично использование JSON в этой ситуации не приносит реальной выгоды, когда ассоциативные массивы PHP настолько мощны. Просто придерживайтесь того, что дает вам язык, и это способ сделать это с помощью PHP.

1 голос
/ 16 мая 2009

Нет 1 способа сделать это в любой версии PHP вплоть до PHP 5.3 включительно.

PHP не поддерживает именованные параметры и / или селекторы в стиле smalltalk / target-c / ruby. PHP также не предлагает способ переопределить эту часть языка. Если вы хотите этого в PHP, вам не повезло. PHP никогда не был лучшим выбором языка для так называемого «метапрограммирования».

Как уже упоминали другие, лучше всего использовать PHP с использованием массива с парами ключ / значение в сочетании с экстрактом.

myFunction(array(
    'theThing'=>0,
    'param2'=>'another value',
));

function myFunction($params){
    extract($params);
    echo $param2;
}   
  1. Вероятно, вы могли бы написать расширение на C / C ++ для расширения PHP с помощью этой возможности, но вы были бы мазохистом. :)
0 голосов
/ 18 июля 2009

Вы можете использовать функцию 'func_get_args()' и просто использовать каждый первый параметр в качестве имени переменной и каждую секунду в качестве значения. Это, вероятно, так же близко, как вы собираетесь добраться до ruby-пути (я долго искал способ сделать это, я точно понимаю, что вы имеете в виду в отношении элегантного решения ruby ​​для массивов). Надеюсь, что в будущем PHP откроет себя для перепрограммирования на выполнение, каким может быть ruby ​​(не знаю, как это на самом деле называется, но именно это делает ruby ​​и ruby ​​на рельсах такими блестящими).

0 голосов
/ 16 мая 2009

Решение - использовать переменные аргументы.

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

function AssociativeArrayFromFlatArray($args)
{
    $nbArgs = count($args);
    if( $nbArgs % 2 != 0 )
    {
        die('This function must have an even number of arguments');
    }

    $ret = array();
    for( $i = 0; $i < $nbArgs; $i += 2 )
    {
        $key = $args[$i];
        $value = $args[$i + 1];
        $ret[$key] = $value;
    }
    return $ret;
}

function DoSomething(/*...*/)
{
    $args = AssociativeArrayFromFlatArray(func_get_args());

    if( $args['action'] == 'greet' )
    {
        $count = $args['count'] or 1;
        for( $i = 0; $i < $count; $i += 1 )
        {
            echo $args['text'];
        }
    }
}

DoSomething('action', 'greet', 'count', 10, 'text', 'Hello World! ');

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

0 голосов
/ 15 мая 2009

Так как все варианты здесь включают вызов array, и, похоже, это "PHPish" способ делать вещи, я добавлю, что если вы делаете это все время, возможно, имеет смысл иметь функция z() (я просто думаю в духе $() в jQuery), которая псевдоним array(). Помимо длины массива имен, я не вижу, насколько версия Ruby более элегантна. Меньше символов, но мне несколько не нравится , что вы не можете сразу определить разницу между параметром функции и парой ключ / значение в этом примере кода.

...