0

我正在尝试将 php 代码片段添加到 Drupal Web 表单节点中。我在 Drupal 查询注释下方的行中出现意外标记“(”附近出现错误消息语法错误。有帮助吗?我转义了括号和美元符号。

#!/usr/bin/perl

use strict;

my $updatesdir = '/var/www/html/mysite/releaseupdates/spint1';
my $drupalroot = '/var/www/html/mysite/web';
my $drushcmd = '/usr/bin/drush';

# Drupal Query
system("$drushcmd -r $drupalroot -u sites.admin --yes sql-query 'update node_revisions set body = REPLACE\(body,\'</div>\',\'<?php \$contact_us_node = abc_drupal_node_load\(NULL, \'my_group\'\);if \(isset\(\$contact_us_node->field_contact_us_message_body\)\) {echo \$contact_us_node->field_contact_us_message_body[0][\'value\'] . \"<br />\";}?></div>\'\) WHERE nid=123'") == 0 or die "$drushcmd failed: $?";
print "Contact Us Body Text updated with PHP Code.\n";
4

1 回答 1

1

您正在将此字符串传递给system,因此您的外壳(已格式化以提高可读性):

/usr/bin/drush
  -r /var/www/html/mysite/web
  -u sites.admin
  --yes sql-query '
    update node_revisions
    set body = REPLACE(body,'</div>',
        '<?php
          $contact_us_node = abc_drupal_node_load(NULL, 'my_group');
          if (isset($contact_us_node->field_contact_us_message_body)) {
            echo $contact_us_node->field_contact_us_message_body[0]['value'] . "<br />";
          }
        ?></div>'
    )
    WHERE nid=123'

为什么?Perl 的双引号字符串通过删除反斜杠来忽略未知的转义。例如:"\(" eq "("。这意味着当 shell 看到该命令时,所有这些反斜杠都不见了!让我们看看 shell 实际看到的是什么“字符串”:

/usr/bin/drush
-r
/var/www/html/mysite/web
-u
sites.admin
--yes
sql-query
'update node_revisions set body = REPLACE(body,'
</div>
','
<?php $contact_us_node = abc_drupal_node_load(NULL,
'my_group'
);if (isset($contact_us_node->field_contact_us_message_body)) {echo $contact_us_node->field_contact_us_message_body[0][
'value'
] .
"<br />"
;}?></div>
') WHERE nid=123'

这绝对不是你想要的。我们有三个级别的转义

  1. Perl 字符串
  2. 贝壳
  3. SQL
  4. (PHP 代码,但这里没有使用任何转义符)

我们如何解决这个问题?我们可以通过直接使用 Perlexec命令而不将其传递给 shell 来删除 shell 级别。为此,我们使用该命令的列表形式:

system(
  $drushcmd,
  '-r', $drupalroot,
  '-u', 'sites.admin',
  '--yes',
  'sql-query',
  "update node_revisions set body = REPLACE\(body,\'</div>\',\'<?php \$contact_us_node = abc_drupal_node_load\(NULL, \'my_group\'\);if \(isset\(\$contact_us_node->field_contact_us_message_body\)\) {echo \$contact_us_node->field_contact_us_message_body[0][\'value\'] . \"<br />\";}?></div>\'\) WHERE nid=123'",
) == 0 or die "$drushcmd failed: $?";

啊,是的,这样更好。我们可以通过使用带有替代分隔符的单引号字符串来进一步消除在 Perl 代码中转义的需要:

q#update node_revisions set body = REPLACE(body,'</div>','<?php $contact_us_node = abc_drupal_node_load(NULL, 'my_group');if (isset($contact_us_node->field_contact_us_message_body)) {echo $contact_us_node->field_contact_us_message_body[0]['value'] . "<br />";}?></div>') WHERE nid=123'#

我们现在已经消除了 Perl 和 shell 的转义级别,所以只剩下 SQL。

于 2014-03-24T21:27:19.993 回答