当php变量/not/从包含的文件中可用时';的范围


When php variables /not/ available from an included file's scope?

我正在为Drupal7开发一个自定义主题,但我有点卡住了。我还没有把这个发布到Drupal stackexchange上,因为我不认为这个问题与Drupal有关——我认为这是一个php语言问题。

基本上,Drupal会查找命名文件,如page.tpl.php、page-front.tpl.php等。实际上,这是我目前仅有的两个。

在我的html.tpl.php文件中,我发现定义页面的整体结构很方便。当访问不同的页面(如页面首页、首页)时,会运行以下代码:

<?php
$subtemplate = "front/content";
include("page.tpl.php");
?>

漂亮又简单。

现在让我们来看看page.tpl.php中的整体HTML结构:

<?php
if(!isset($subtemplate)) {
   $subtemplate = "test";
}?>
<html> (etc)
...
<?php print "from main template file:" . $content_column_class; ?>
<?php $x="hello"; ?>
<?php include "pages/$subtemplate.tpl.php"; ?>

也很简单$content_column_class由主题提供,$x只是一个测试字符串。

现在在我们的子模板文件pages/test.tpl.php中:

<?php echo $x; ?>
<?php print "from sub template file:" . $content_column_class; ?>

你会期望输出是这样的:

from main template file: class="col-sm-12" 
from sub template file: class="col-sm-12" 
hello

事实上,输出是这样的:

from main template file: class="col-sm-12" 
Notice: Undefined variable: x in include() (line 1 of /buildkit/build/CiviCRM/sites/all/themes/common/templates/pages/test.tpl.php).   
Notice: Undefined variable: content_column_class in include() (line  1 of /buildkit/build/CiviCRM/sites/all/themes/common/templates/pages/test.tpl.php).

我就是不明白。事实上,在我作为php开发人员的这些年里,我从未见过这样的事情。每次我使用include()语句或其家族require、require_eonce等时,脚本执行都会在包含的文件中停止的地方继续,并且变量对包含的脚本是/始终/可用的。事实上,我认为这样改变include()的行为是不可能的。

现在,我可以解决这个问题:

<?php global $x; ?>
<?php global $content_column_class; ?>
<?php echo $x; ?>
<?php print "from subtemplate:" . $content_column_class; ?>

现在输出如预期:

from main template file: class="col-sm-12" 
from sub template file: class="col-sm-12" 
hello

使用全局关键字是不雅的,通常不建议使用。有没有更简单、更简单的方法?我担心,如果我走这条路,不可避免地会有我忘记全球化的变量。

我唯一能找到的可能是Wordpress的这篇论坛帖子:https://wordpress.org/support/topic/passing-php-variable-between-template-files:

WordPress不会让你像在非WP网站上那样包含变量。一种方法是在页面上使用自定义字段,并使用该字段中的值来确定要加载的样式表。

然而,他们实际上并没有说/如何/有可能做到这一点。

调试回溯并不是特别有用:

 #0  include() called at [/buildkit/build/CiviCRM/sites/all/themes/common/templates/page.tpl.php:100]  
 #1  include(/buildkit/build/CiviCRM/sites/all/themes/common/templates /page.tpl.php) called at [/buildkit/build/CiviCRM/includes/theme.inc:1525]
 #2  theme_render_template(sites/all/themes/common/templates/page.tpl.php, Array ([page] => Array ([#show_messages] => 1,[#theme] => page,[#theme_wrappers] => Array ([0] => html),[#type] => page,[#icon] => ,[#icon_position] => before,[#process] => Array ([0] => bootstrap_form_process),[#pre_render] => Array ([0] => bootstrap_pre_render),[content] => Array ([workbench_block] => Array ([#markup] => ...

有可能吗?有人能帮助我了解这里可能发生的事情以及如何克服吗?

主题是Drupal Bootstrap的一个儿童主题,我认为这并不重要。

当您使用已经编码的东西时,可能很难集成一些东西。你有没有看一下标准Drupal主题模块的内部,你有没有看到它们是如何进行的?

当Drupal切换到版本6时,我已经停止使用它了,所以我不知道它现在是如何工作的。

来自Drupal 7,关于主题化的官方文档:

  • 主题公司
  • 使用主题图层
  • 设置模板中使用的变量(预处理和处理函数)

我认为你应该按照它们的建议注册你的变量,尤其是在第三个环节。