【问题标题】:variable predefinition, moving variable to earlier point变量预定义,将变量移动到更早的点
【发布时间】:2009-12-26 18:50:09
【问题描述】:

好的,这就是我真正陷入困境的交易。

我将我的 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% 的情况下一切正常。但是,在某些情况下,我需要获取变量的内容(在左侧模块中),它只会在 NEXT SIDE 中定义(例如在右侧模块中)

使用我的代码,我可以在“标题模块”中定义站点标题,但是如果我需要,我可以在 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);
   <...>
}

现在谈谈我的问题。

如何对变量做同样的事情:

LEFT SIDE 模块中我有一句话(问题:$object):

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

RIGHT SIDE 模块中我有句子(问题:$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(如果 GOTO 解决方案是可能的(?))?


我个人认为是不可能编码的,但是自从Php 5.3.0以后有可能,我变得很可能被编码了。不幸的是,我不确定公司是否会在他们的服务器上使用 Php 5.3.0,所以我希望有其他解决方案。

此外,我仍然不确定 GOTO 是否会有所帮助。

【问题讨论】:

  • 我不明白你所说的左侧模块和右侧模块是什么意思。
  • 所有网站都是一个对象容器,分为 3 个部分供主题设计师使用:左侧面板(及其渲染代码)、右侧面板和中心面板。这允许在不了解 PHP 的情况下更改设计器主站点对象的顺序。

标签: php scope php-5.3 goto


【解决方案1】:

我建议重新考虑您的架构。

无意冒犯,但代码在我看来相当混乱。

指出几点:

  • 你说你使用Design Patterns,但唯一的模式似乎是Template View。您似乎没有使用MVC,也没有使用Two-Step View,这两者都适合您的情况。
  • 您不使用OOP 有什么特别的原因吗?并不是说程序化编码是一件坏事,而是正确的encapsulation of things that conceptually go togetherseparation of concerns 会让你的应用更易于维护。
  • 您的变量名没有意义。 $output0 真的没有告诉你里面有什么。为什么$object 持有一个数字?您的函数名称也是如此:push_to_sql()change_to_sql() 听起来很相似。我猜一个意思是 insert,一个意思是 update,但语义可能更清晰。
  • 为什么要将保存内容块的variables 分配给constants?这一步完全是多余的,因为您也可以在模板视图中使用变量。

现在,我了解到您在问题描述中使用了示例代码,如果我提到了不适用于您的生产代码的点,请多多包涵。但是,您的模块无法在不影响另一个模块的情况下重新排列这一简单事实表明code smell。模块应该是独立的。

但是让我们现在解决您的问题。

您说您需要将变量提交到源中的较早点。我对示例代码的理解不足以找出原因。但是如果你必须保持你的Big Ball of Mud当前架构,你可以refactor将模块之间共享的所有代码放到一个单独的函数中。然后预加载所有需要的数据并将其注入到渲染内容块的函数中。这样一来,您应该可以随心所欲地推动它们。

如果您不必保留当前架构,请帮自己一个忙,看看上面链接的模式。大多数PHP frameworks 都使用它们,您可能需要考虑将您的应用程序迁移到一个上。要进一步改进您的代码,请查看这些 QA tools 并查看以下网站:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 2011-11-30
    相关资源
    最近更新 更多