Функции переменных и имена переменных в PHP - PullRequest
1 голос
/ 24 октября 2009

В PHP скажем, что у вас есть такой код:

$infrastructure = mt_rand(0,100);
if ($infrastructure < $min_infrastructure) $infrastructure = $min_infrastructure;
//do some other stuff with $infrastructure
$country->set_infrastructure($infrastructure);

$education = mt_rand(0,100);
if ($education < $min_education) $education = $min_education;
//do some other stuff with $education
$country->set_education($education);

$healthcare = mt_rand(0,100);
if ($healthcare < $min_healthcare) $healthcare = $min_healthcare;
//do some other stuff with $healthcare
$country->set_healthcare($healthcare);

Есть ли способ объединить эти похожие наборы инструкций в функцию, которая может быть вызвана следующим образом:

change_stats("infrastructure");
change_stats("education");
change_stats("healthcare");

Как правило, можете ли вы использовать переменные в PHP в других именах переменных и именах функций?

Заранее спасибо.

Ответы [ 5 ]

3 голосов
/ 24 октября 2009

Вы можете использовать то, что PHP называет «переменные переменные» , чтобы сделать это. Я надеюсь, что ваш пример надуманный, так как выглядит немного странно, но, предполагая, что переменные и объекты являются глобальными, вы можете написать функцию name_pet () следующим образом:

function name_pet($type, $name)
{
    $class='the_'.$type;
    $var=$type.'_name';

    $GLOBALS[$class]->setName($name);
    $GLOBALS[$var]=$name;
}

РЕДАКТИРОВАТЬ : этот ответ относится к более ранней версии вопроса .

0 голосов
/ 24 октября 2009

Это интересный вопрос, потому что это распространенная схема, и на нее особенно важно обращать внимание при рефакторинге.

В чисто функциональном смысле вы можете использовать такой код:

function rand_or_min( $value, $key, $country ) {
  $rand = mt_rand(0,100);
  if ($rand < $value ) { $rand = $value; }
  // do something
  call_user_func( array( $country, 'set_' . $value ), array( $rand ) );
}

$arr = array('infrastructure' => 5,'education' => 3,'healthcare' => 80);
array_walk( $arr, 'rand_or_min', $country );

Хотя вышесказанное работает хорошо, я настоятельно рекомендую вам использовать более объектно-ориентированный путь. Всякий раз, когда вы видите шаблон, подобный приведенному выше, вы должны думать о классах и подклассах. Зачем? Потому что есть дублированное поведение и подобное состояние (переменные).

В более широком смысле это может быть реализовано так:

class SomeBasicBehavior {

   function __construct( $min = 0 ) {
      $rand = mt_rand(0,100);
      if( $rand < $min ) { $rand = $min };
      return $rand;
   }

}

class Infrastructure extends SomeBasicBehavior {
}

class Education extends SomeBasicBehavior {
}

class Healthcare extends SomeBasicBehavior {
}

$country->set_infrastructure( new Infrastructure() );
$country->set_education( new Education() };
$country->set_healthcare( new Healthcare() };

Мало того, что он гораздо более читабелен, но также гораздо более расширяем и тестируем. Ваше «сделать что-то» может быть легко реализовано как функции-члены в каждом классе, и их поведение может быть настолько общим, насколько это необходимо (с использованием класса SomeBasicBehavior), или таким инкапсулированным, как вам требуется.

0 голосов
/ 24 октября 2009

Да, возможно, посмотрите здесь для обсуждения и здесь для учебника.

0 голосов
/ 24 октября 2009

Чтобы ответить на ваш вопрос: Да, вы можете использовать переменные в качестве имен переменных, используя синтаксис $ {$ varname}.

Однако это, похоже, не является правильным решением для того, что вы пытаетесь здесь сделать, поскольку установка переменных $ _ _ $ $ name} требует, чтобы они находились в области действия функции name_pet.

Не могли бы вы подробнее рассказать о том, что вы пытаетесь сделать?

Несколько советов: пусть класс питомца (или что-то еще, что такое кошка, собака и рыба) возвращает заданное имя, чтобы вы могли сделать $ fish_name = $ the_fish-> setName ("Goldie");

Или, что еще лучше, вообще не используйте $ fish_name, поскольку эта информация теперь хранится в объекте ... вы можете просто вызвать $ the_fish-> getName (); где вы будете использовать $ the_fish.

Надеюсь, это поможет?

0 голосов
/ 24 октября 2009

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

$data;
function __set($key, $val) {
 $this->data["$key"] = $val;
}

И да, вы можете использовать переменные динамически

$foo = "bar";
$dynamic = "foo";

echo $$dynamic; //would output bar
echo $dynamic; //would output foo
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...