предопределение переменной, перемещение переменной в более раннюю точку - PullRequest
0 голосов
/ 26 декабря 2009

Хорошо, вот сделка, в которой я действительно застрял.

Я использую мои cms с шаблонами дизайна. Где последний конечный результат (в основном файле шаблона дизайна: 'design.php'):

<div>{CONTENT_HEADER}</div>
<div style='float:left;width:25%'>{CONTENT_LEFT}</div>
<div style='float:left;width:50%'>{CONTENT_CENTER}</div>
<div style='float:left;width:25%'>{CONTENT_RIGHT}</div>
<div>{CONTENT_FOOTER}</div>

Где CONTENT_XXXX - это модули сайта генерации мыслей:

ob_start("gz_handler");
<....... LOAD ALL THE HEADER MODULES .......>
$output0 = ob_get_contents();
ob_end_clean();

ob_start("gz_handler");
<....... LOAD ALL THE LEFT SIDE MODULES .......>
$output1 = ob_get_contents();
ob_end_clean();

ob_start("gz_handler");
<....... LOAD ALL THE CENTER SIDE MODULES .......>
$output2 = ob_get_contents();
ob_end_clean();

ob_start("gz_handler");
<....... LOAD ALL THE RIGHT SIDE MODULES .......>
....
// That's I talk about, but this is just for static html, not variables
// Push to header finalizers to override default <title></title>
$header_finalizers_array['change_head_title_attr_to'] = $thread_data['topic_title'];
<....... END OF ALL THE RIGHT SIDE MODULES .......>
$output3 = ob_get_contents();
ob_end_clean();

ob_start("gz_handler");
<....... LOAD ALL THE FOOTER MODULES .......>
$output5 = ob_get_contents();
ob_end_clean();

define("CONTENT_HEADER", finalize_output($output0,$header_finalizers_array));
define("CONTENT_LEFT", finalize_output($output2,$left_finalizers_array));
define("CONTENT_CENTER", finalize_output($output3,$center_finalizers_array));
define("CONTENT_RIGHT", finalize_output($output4,$right_finalizers_array));
// No need finalizations, because there are no more parts, which call content changes
define("CONTENT_FOOTER", $output5);

Все в порядке в 95% случаев. Но в некоторых случаях мне нужно ПОЛУЧИТЬ СОДЕРЖАНИЕ ПЕРЕМЕННОГО (в левых боковых модулях), которое ТОЛЬКО будет определено в СЛЕДУЮЩЕЙ СТОРОНЕ (например, в правых боковых модулях)

С помощью своего кода я могу определить заголовки сайта в «модулях заголовка», но затем, если я этого захочу, я могу изменить его в ex. справа, потому что я могу добавить в массив требование замены данных, которое будет выполнено после того, как все содержимое сторон будет преобразовано в переменные, но ДО печати в браузер клиента.

Все это можно сделать только с 1 строкой в ​​функции:

function finalize_output($output="",$fin_array=array()) {
   <...>
   $output = preg_replace("#<title>.*</title>#i", "<title>".$fin_array['change_head_title_attr_to']."</title>", $output, 1);
   <...>
}

Теперь о моей проблеме.

Как сделать то же самое с переменными:

IN ЛЕВАЯ СТОРОНА модулей У меня есть предложение (ПРОБЛЕМА: $ object ):

if(isset($object)) {
  $best_product = sqlArray(sqlQuery("SELECT * FROM tableA WHERE b='$object'"));
 <..All the rest code of BEST's product..>
}

IN ПРАВАЯ СТОРОНА модули У меня есть смысл (ПРОБЛЕМА: $ object ):

<... Print LAST 10 PRODUCTS ***>
$res = sqlquery("SELECT * FROM tableA ORDER BY id DESC LIMIT 100);
while($data = sqlarray($res)) { <..PRINT PRODUCT INFO..> }

$new = rand(0,secured($_POST['user_input_new_products']));
for($i=1;$i<=$new;$i++) {
  $price_diff_old_new1 = change_products_to_sql('fish_$i', 19.99);
  $price_diff_old_new2 = push_product_to_sql('crab_$i', 16.99);
  if($i==$new) {
    $object = $price_diff_old_new1+$price_diff_old_new2;
  }
}

ЭТО ПРОСТО ПРИМЕРНЫЙ КОД, ЧТО Я ДОЛЖЕН ДЕЛАТЬ (так что не будем вдаваться в подробности), но ТОЧКА ЭТОГО , что Мне нужно как-то передать переменную в более раннюю точку источника : Одним из решений будет « USE GOTO », но будет ли эта переменная запомнена.

Я имею в виду:

echo "JOB IS STARTED";
  LABEL HOME:
   <INCLUDED FILE : procuts.php >
      if(isset($object) && check_is_number($object)) {
       $a = $object;
      }
      if(isset($break_me) && $break_me) {
        GOTO FINAL;
      }
   <END OF INCLUDE>
   ...

 <INCLUDED FILE : upload.php >
    $object = 999;
    $break_me = true;
    GOTO HOME;
  <END OF INCLUDE>
}
 LABEL FINAL: 
echo "JOB IS DONE";

И, есть ли другой способ сделать это БЕЗ ПЕРЕХОДА (если GOTO-решение возможно (?))?


Я лично думал, что это невозможно, но с Php 5.3.0 это возможно, и я, вероятно, буду закодирован. К несчастью, я не уверен, что компания будет использовать Php 5.3.0 на своих серверах, поэтому я надеюсь, что есть другие решения.

Также я все еще не уверен, что даже GOTO поможет там.

1 Ответ

1 голос
/ 27 декабря 2009

Я предлагаю переосмыслить вашу архитектуру.

Без обид, но код выглядит для меня довольно грязно.

Чтобы указать на несколько вещей:

  • Вы сказали, что используете Шаблоны проектирования , но, похоже, единственным шаблоном является Шаблонное представление . Похоже, вы не используете MVC или Двухэтапный просмотр , которые оба подойдут в вашем случае.
  • есть ли какая-то особая причина, по которой вы не используете ООП ? Дело не в том, что процедурное кодирование - это плохая вещь, но правильная инкапсуляция вещей, которые концептуально сочетаются и разделение интересов , сделает ваше приложение более удобным в обслуживании.
  • имена ваших переменных не имеют значения. $output0 действительно ничего вам не говорит о том, что внутри. Почему $object содержит номер? То же самое относится и к именам ваших функций: push_to_sql() и change_to_sql() звучат одинаково. Полагаю, одно означает insert , а другое - update , но семантика может быть намного понятнее.
  • Почему вы присваиваете переменные , удерживающие ваши блоки содержимого для констант ? Этот шаг совершенно лишний, так как вы также можете использовать переменные в вашем шаблонном представлении.

Теперь я понимаю, что вы использовали пример кода в описании вашего вопроса, так что потерпите меня, если я затронул вопросы, не применимые к вашему производственному коду. Но все же тот простой факт, что ваши модули не могут быть переставлены без влияния на другие, указывает на запах кода . Модули должны быть автономными.

Но давайте теперь перейдем к вашей проблеме.

Вы говорите, что должны передать переменную в более раннюю точку источника. Я не достаточно понимаю пример кода, чтобы понять, почему. Но если вам необходимо сохранить текущую архитектуру Big Ball of Mud , вы можете рефакторировать весь код, который будет совместно использоваться модулями в отдельной функции. Затем предварительно загрузите все необходимые данные и вставьте их в функции, отображающие блоки содержимого. Таким образом, вы сможете толкать их как хотите.

Если вам не нужно сохранять свою текущую архитектуру, сделайте себе одолжение и взгляните на шаблоны, связанные выше. Большинство PHP-фреймворков используют их, и вы можете подумать о переносе своего приложения на одно из них. Чтобы еще больше улучшить свой код, взгляните на эти QA tools и проверьте эти сайты:

...