Drupal_static的预期用途是什么? -- 7 领域 drupal 相关 的问题

What is the intended use of drupal_static?


6
vote

问题

中文

我理解Drupal静态缓存用于存储内存中的静态值,以便更快地访问它们的要求。然而,在德鲁佩尔和贡献的模块中,我倾向于看到两个不同的版本:

示例来自 drupal_is_front_page :

  function drupal_is_front_page() {   // Use the advanced drupal_static() pattern, since this is called very often.   static $drupal_static_fast;   if (!isset($drupal_static_fast)) {     $drupal_static_fast['is_front_page'] = &drupal_static(__FUNCTION__);   }   $is_front_page = &$drupal_static_fast['is_front_page'];    if (!isset($is_front_page)) {     // As drupal_path_initialize updates $_GET['q'] with the 'site_frontpage' path,     // we can check it against the 'site_frontpage' variable.     $is_front_page = ($_GET['q'] == variable_get('site_frontpage', 'node'));   }    return $is_front_page; }   

他们从发现的某些教程中读取(和使用)它:

  $static_cache = &drupal_static(__FUNCTION__); if (!isset($static_cache[$key])) {   // Obtain value   $static_cache[$key] = $obtained_value; }  return $static_cache[$key];   

所以我跳过了局部变量的静态声明,并且要诚实地看出我不明白为什么我应该添加它,它位于 drupal_static :

  function &drupal_static($name, $default_value = NULL, $reset = FALSE) {   static $data = array(), $default = array();   // First check if dealing with a previously defined static variable.   if (isset($data[$name]) || array_key_exists($name, $data)) {     // Non-NULL $name and both $data[$name] and $default[$name] statics exist.     if ($reset) {       // Reset pre-existing static variable to its default value.       $data[$name] = $default[$name];     }     return $data[$name];   }   ... }   

如果我声明我的模块中的另一个静态变量以保存管理静态变量的函数,则甚至更快? (drupal_static_fast的名称意味着这个。)这个旧的drupal 6公约,没有drupal_static,它必须在本地宣布?或者我错过了别的东西?

英文原文

I understand Drupal static cache is used to store static values in the memory for the length of the request to faster access them. However throughout Drupal and contributed modules I tend to see two different versions:

Example from drupal_is_front_page:

function drupal_is_front_page() {   // Use the advanced drupal_static() pattern, since this is called very often.   static $drupal_static_fast;   if (!isset($drupal_static_fast)) {     $drupal_static_fast['is_front_page'] = &drupal_static(__FUNCTION__);   }   $is_front_page = &$drupal_static_fast['is_front_page'];    if (!isset($is_front_page)) {     // As drupal_path_initialize updates $_GET['q'] with the 'site_frontpage' path,     // we can check it against the 'site_frontpage' variable.     $is_front_page = ($_GET['q'] == variable_get('site_frontpage', 'node'));   }    return $is_front_page; } 

They way I read (and used) it from some tutorial I once found:

$static_cache = &drupal_static(__FUNCTION__); if (!isset($static_cache[$key])) {   // Obtain value   $static_cache[$key] = $obtained_value; }  return $static_cache[$key]; 

So I skipped the static declaration of the local variable, and to be honest I don't see why I should be adding it, it is in the first line of drupal_static:

function &drupal_static($name, $default_value = NULL, $reset = FALSE) {   static $data = array(), $default = array();   // First check if dealing with a previously defined static variable.   if (isset($data[$name]) || array_key_exists($name, $data)) {     // Non-NULL $name and both $data[$name] and $default[$name] statics exist.     if ($reset) {       // Reset pre-existing static variable to its default value.       $data[$name] = $default[$name];     }     return $data[$name];   }   ... } 

Is is even faster if I declare another static variable in my module to hold a function that manages a static variable? (The name drupal_static_fast implies this.) Is this some old Drupal 6 convention where there was no drupal_static and it had to be declared locally? Or am I missing something else?

  
   
   

回答列表

8
 
vote
vote
最佳答案
 

drupal_is_front_page() 中的代码使页面渲染更快,因为它调用 drupal_static() 每一个页面请求;它使它取决于称为drupal_is_front_page() 的次数取决于多少次。它使用该代码的事实意味着核心维护者知道该函数被称为足够的时间需要该代码。
drupal_static() 文档用以下段落解释:

在少数情况下,函数需要可重置的静态变量,但是在单页请求期间,该函数称为多次(100+),因此可以从函数计数中删除的每秒执行时间。这些功能可以使用更繁琐的,但呼叫 $this->addFieldMapping('csv_birthday_column', 'new_profile2_birthday_field'); 0 的更快的变体。它通过存储 $this->addFieldMapping('csv_birthday_column', 'new_profile2_birthday_field'); 1 返回的引用在调用函数自己的静态变量中存储,从而删除了调用 $this->addFieldMapping('csv_birthday_column', 'new_profile2_birthday_field'); 2 的需要进行函数的每个迭代。概念上,它取代了:

  $this->addFieldMapping('csv_birthday_column', 'new_profile2_birthday_field'); 3  

  $this->addFieldMapping('csv_birthday_column', 'new_profile2_birthday_field'); 4  
但是,上面的代码行不起作用,因为PHP仅允许通过文字值初始化静态变量,并且不允许将静态变量分配给参考。
  • http://php.net/manual /language.variables.scope.php#language.variables.scope.static
  • http://php.net/manual /language.variables.scope.php#language.variables.supe.references

下面的示例显示了在两个限制上工作所需的语法。对于基准和更多信息,请参阅 http://drupal.org/node/619666 。

  $this->addFieldMapping('csv_birthday_column', 'new_profile2_birthday_field'); 5  

您的代码调用 $this->addFieldMapping('csv_birthday_column', 'new_profile2_birthday_field'); 6 每次,并且基本上是与以下一个的代码相同,在Drupal文档中不被视为快速版本。

  $this->addFieldMapping('csv_birthday_column', 'new_profile2_birthday_field'); 7  

@clive解释了原因 $this->addFieldMapping('csv_birthday_column', 'new_profile2_birthday_field'); 8 被添加到drupal:实现后面的想法是使用静态变量,同时可以从其他功能重置(或更改)。实际上, $this->addFieldMapping('csv_birthday_column', 'new_profile2_birthday_field'); 9 文档说:

鼓励需要静态变量持续或缓存数据的所有函数在单页请求中使用此功能,除非它绝对确定在页面请求期间不需要重置静态变量。通过通过此功能集中静态变量存储,其他功能可以依赖于一致的API来重置任何其他函数的静态变量。

 

The code in drupal_is_front_page() makes the page rendering faster because it calls drupal_static() once for each page request; how much faster it makes it depends from how many times drupal_is_front_page() is called. The fact it is using that code means the core maintainers know the function is called enough times to need that code.
The drupal_static() documentation explains this with the following paragraph:

In a few cases, a function needs a resettable static variable, but the function is called many times (100+) during a single page request, so every microsecond of execution time that can be removed from the function counts. These functions can use a more cumbersome, but faster variant of calling drupal_static(). It works by storing the reference returned by drupal_static() in the calling function's own static variable, thereby removing the need to call drupal_static() for each iteration of the function. Conceptually, it replaces:

$foo = &drupal_static(__FUNCTION__); 

with:

// Unfortunately, this does not work. static $foo = &drupal_static(__FUNCTION__); 

However, the above line of code does not work, because PHP only allows static variables to be initialized by literal values, and does not allow static variables to be assigned to references.

  • http://php.net/manual/language.variables.scope.php#language.variables.scope.static
  • http://php.net/manual/language.variables.scope.php#language.variables.scope.references

The example below shows the syntax needed to work around both limitations. For benchmarks and more information, see http://drupal.org/node/619666.

function user_access($string, $account = NULL) {   // Use the advanced drupal_static() pattern, since this is called very often.   static $drupal_static_fast;   if (!isset($drupal_static_fast)) {     $drupal_static_fast['perm'] = &drupal_static(__FUNCTION__);   }   $perm = &$drupal_static_fast['perm'];   // ... } 

Your code calls drupal_static() every time, and essentially is the same code as the following one, which in Drupal documentation is not considered the fast version.

  $added = &drupal_static(__FUNCTION__);    // User-uploaded files cannot set any response headers, so a custom header is   // used to indicate to ajax.js that this response is safe. Note that most   // Ajax requests bound using the Form API will be protected by having the URL   // flagged as trusted in Drupal.settings, so this header is used only for   // things like custom markup that gets Ajax behaviors attached.   if (empty($added)) {     drupal_add_http_header('X-Drupal-Ajax-Token', '1');     // Avoid sending the header twice.     $added = TRUE;   } 

@Clive explained the reason drupal_static() was added to Drupal: The idea behind its implementation was to use a static variable that at the same time could be reset (or changed) from other functions as well. In fact, the drupal_static() documentation says:

All functions requiring a static variable to persist or cache data within a single page request are encouraged to use this function unless it is absolutely certain that the static variable will not need to be reset during the page request. By centralizing static variable storage through this function, other functions can rely on a consistent API for resetting any other function's static variables.

 
 
   
   

相关问题

1  如何在规则操作中替换关于[node:url]的文本吗?  ( How to replace text about nodeurl within a rules action ) 
我正在使用规则模块,并在保存新时创建规则内容,发送电子邮件包含节点标题,以及节点的URL。非常直接。也就是说,我想在发送的消息之前替换网址中的文本。我正在使用str_replace(),但它不起作用。 任何建议? 更新: 路径当前看起来像这样: domain.com/cron.php/newsroom/press-...

0  单击链接时,从表中检索值并显示在WebForm字段上  ( When a link is clicked a value is retrieved from the table and displayed on a w ) 
我创建了一个带有两个按钮的基本页面,"是" 和"否" 。单击"是" 按钮时,它将引导到WebForm。 目的:当出现WebForm时,它会将表中的值显示为字段。 数据库 表名:房间 领域:房间 数据:培训室 基本页 webform 我为此功能创建了一个模块: test_presa...

0  devel dpq()不起作用?  ( Devel dpq not working ) 
我正在尝试打印从视图生成的SQL,但它不起作用。以下是我获得的错误消息: - Fatal error: Call to a member function arguments() on a non-object in /var/www/Exaxmple-Site/sites/all/modules/devel...

1  从自定义URL删除语言前缀  ( Remove language prefix from custom url ) 
我们的网站存在于多种语言中。我已安装XMLSitemap模块和默认链接看起来像SitEname / en / sitemap.xml 我需要删除此链接的语言前缀。似乎没有设置为任何特定的自定义链接禁用翻译。 可以是我可以以编程方式做到这一点? ...

1  在不使用拖放的情况下编辑块的权重  ( Edit weight of block without using drag and drop ) 
我正在尝试重新排序块。我明白它可以通过拖放块结构页面拖放来完成,但是我有一个限制。 保存时,订单不会保存。这很可能是因为存在非常大量的块,服务器无法以一种形式处理许多输入。所以它只是恢复到它的原始位置。我无法访问服务器,因此我无法进行更改以允许服务器处理许多输入。 我也无法访问MySQL数据库。 我希望能够在块中手动...

2  如何为从未访问一个站点的用户创建视图过滤器?  ( How to create a views filter for users who have never accessed a site ) 
我有一个景观,我正在尝试显示所有具有 never 的上次访问值的用户,这意味着它们从未登录过。 滤波器期望日期值对我没有帮助,因为我只需要通过从未访问的用户过滤。 任何人都知道围绕这个方法吗? ...

2  如何看到*哪个用户*最后更新了一个节点?  ( How do i see which user last updated a node ) 
在 admin/content 中,我如何覆盖这个显示屏列表上次更新一段内容的用户。我们可以看到最初的作者,这很好。但我想要一个触摸节点的跑步道。 我尝试了什么 修订:但是,某些内容类型使用jQuery选项卡的字段,在返回某一修订时丢失其内容。 ...

2  如何使用外部JSON API创建/更新节点的字段?  ( How to use external json api to create update nodes fields ) 
我有一个内容类型: siteinfo 。 此内容类型具有多个字段:文本,实体参考等。 我想使用外部API自动填充创建节点的某些字段。 我想要使用的API说: API返回XML&amp中的一致和结构​​良好的数据;杰森 格式。返回的数据包含可容易的解析字段 您的申请使用。这是一个基于RES的API。 ...

1  WebForm草案共享链接  ( Webform draft share link ) 
我想创建一个接受两方输入的WebForm。第一方填写了表格的一部分,并与第二方分享了与其余的联系。 我已找到对此服务有用的"保存草稿" 功能,但仅加载PreS保存的信息。无论如何我可以共享一个链接(基于SID),以便每当URL具有SID参数时,它会加载预保存的信息? 感谢 ...

0  类似/相关标签块  ( Similar related tags block ) 
有很多方法可以根据其标签构建类似的内容块。是否有任何方法可以构建类似的标签块? 我尝试构建类似/相关的标签块。 我想查看他们拥有的内容和常见标签。他们一起添加了多少次。这样的东西: 例如:对于First Column Green类似于蓝色。对于绿色的第三列黄色和蓝色。 ...

0  使用自定义模块从基本页面存储URL  ( Storing a url from a basic page using a custom module ) 
我在 http://example.com/[company ] / [客户]?ID = 2 。我想将此URL存储在自定义模块中的字符串操作的全局变量中。 我通过使用 hook_form_alter() webform 来取得成功检索URL,但我不知道如何为基本页面做同样的事情。 我需要使用哪个钩子? ...

3  通过自定义表格传递参数  ( Pass argument in view from custom form ) 
我有一个查看内容页面。我想在自定义表单数据的基础上过滤其内容。 所以我们如何使用自定义表单数据来通过或过滤视图内容? 视图构建在节点上。在此特定节点中,我们有一个字段类型选择列表。 我们在我们的表单中创建的相同选择列表。现在以表单选择了什么选择,我们希望在视图中使用它的值。 我们也没有想法如何使用它的价值。 ...

2  menu_tree_all_data()返回自定义菜单的空数组  ( Menu tree all data returns empty arrays for custom menus ) 
这是作品。 $tree = menu_tree_all_data('main-menu'); 这不起作用。 $tree = menu_tree_all_data('menu-health-center'); 为什么<代码> function events_theme($existing, $typ...

1  如何数据比较Ubercart的价格或小计量级运输报价  ( How to data compare the price or subtotal in ubercart flat rate shipping quotes ) 
使用drupal 7.43和 ubercart 7.3.9 我试图为两个参数设置平面运输。 用于小计以上$ 34.00 的订单 用于小计以下34.00美元的订单 不幸的是,小计的数据比较下没有任何选项......只有订单总数。 或者,我想创建一个由价格范围而不同的固定利率运费。 价格高于34.00美元的产品 ...

2  读取字段值并将其传递给仅针对节点页面的段样式Atributes  ( Read field value and pass it to section style atributes only for node page ) 
我在内容类型中有一个颜色字段 - &gt;页面字段。我想读取此字段的值,并将此值传递为主内容的元素的背景颜色(Bootstrap Subtheme)( - 从页面,TLP.php)。并且仅适用于节点类型 - &gt;页面。 在我的template.php中,我试图使用函数theme_preprocess_page。我...

1  如何将饲料内容导入书籍的子页面?  ( How to import feed content as child pages of a book ) 
我能够使用csv和feed导入导入节点,但我希望导入的内容是特定书的子页面。怎么办? ...

2  如何在地图后输入GMAP标记?  ( How to acces gmap markers after map is generated ) 
我有谷歌地图标记出现问题,我没有找到解决方法的方法。 我有一个使用 gmap 模块生成的地图查看,其中我显示某些节点。我还有一个视图块,显示在未格式化的列表中的地图中显示的一些相同节点。我需要的是将列表上的节点与其各自的标记相关联(因此悬停列表更改标记图标,反之亦然)。 我可以将节点与标记相关联,因为我收到了与标记...

2  如何显示由VBO提交填充的表格?  ( How to display a form filled by a vbo submission ) 
我想使用模块将消息发送给一组用户。为此目的,我计划使用视图批量操作(vbo)和大量暴露过滤器。 我能够创建一个自定义vbo-action,将所选用户放入消息表单的收件人字段中: function mymodule_my_custom_action(&$user, $context=array()) { modu...

0  TB-Megamenu如何单击“在移动设备中打开/关闭子菜单  ( Tb megamenu how to click to open close sub menu in mobile ) 
我们试图在移动浏览器上"点击" 菜单选项时仅显示子菜单。此功能在悬停时良好工作,但有些移动设备不适用于悬停。我们需要能够单击子菜单标题以便向下删除,然后再次单击它们以折叠它们。 ...

2  吹嘘狗屎笨拙的安装  ( Drush with a dockerized drupal install ) 
我正在尝试使用Docker设置Drupal的开发环境。 我已经成功地使用官方图像为两者创建PostgreSQL容器和一个Drupal容器,我可以复制生产环境。 如何淹没检测我的drupal安装? 我已经尝试了两个 https://hub.docker.com/r/drush/ drush / 和 https://...




© 2021 it.wenda123.org All Rights Reserved. 问答之家 版权所有


Licensed under cc by-sa 3.0 with attribution required.