2011-08-16 28 views
2

我真的不知道事實與這個問題有關,所以我會從頭開始。PHP:奇怪的函數行爲取決於我如何包含它所包含的腳本?我不知所措

我有一些文本,我想在插入模板之前格式化Markdown風格的URL,但我不希望它們被包裝在<的p >或任何其他塊級別的標記中。

爲此,我通過PHP Markdown代碼工作,隔離了URL格式化所需的東西,並將函數一起放入名爲'MarkdownUrl.php'的文件夾中,該文件夾位於包含路徑。

我會在底部發布該代碼。

現在,讓我們來測試一下:

<?php 

require_once 'functions/MarkdownUrl.php'; 

$text = "Hello, world. [This is a link.](http://www.google.com)"; 

echo MarkdownUrl($text); 

?> 

輸出:

你好,世界。 This is a link.

到目前爲止這麼好。

我還在包含路徑中有一個名爲'loader.php'的文件。它包含一個類自動加載功能,它註冊到spl_autoload_register()和另一個函數loadFunc()這將require_once一個php文件從'functions'目錄根據它傳遞的名稱。後者是重要的。

<?php 

function loadFunc($funcName) 
{ 
    if (!function_exists($funcName)) { 
     require_once 'functions/' . $funcName . '.php'; 
    } 

} 

function loadClass($className) 
{ 
    if (!class_exists($className, false)) { 
     $classPath = str_replace('_', '/', $className); 
     require_once 'classes/' . $classPath . '.php'; 
    } 

} 

spl_autoload_register('loadClass'); 

?> 

忽略「個爲什麼」,幷包括以這種方式代碼的時刻,「wherefores」下面應該有效地等同於測試代碼我在前面貼了,對不對?

<?php 

require_once 'loader.php'; 
loadFunc('MarkdownUrl'); 

$text = "Hello, world. [This is a link.](http://www.google.com)"; 

echo MarkdownUrl($text); 

?> 

而且,可是...輸出:

你好,世界。 [這是一個鏈接。](http://www.google.com)

在運行上述操作時不會發生錯誤。

而且,我已經證實,功能MarkdownUrl()被調用(至少,測試echo我插在函數的頂部發射)。

然而,輸出是未格式化的。 WTF?

一對夫婦的我 - 不 - 肯定 - 如果-這些事項不惜一切細節:共享虛擬主機,包括通過在測試腳本運行在目錄php.ini文件中指定的路徑


內容MarkdownUrl.php的:

<?php 

$nested_brackets_depth = 6; 
$nested_url_parenthesis_depth = 4; 
$no_entities = false; 

function doAnchors_inline_callback($matches) { 
    $whole_match = $matches[1]; 
    $link_text  = $matches[2]; 
    $url   = $matches[3] == '' ? $matches[4] : $matches[3]; 
    $title   =& $matches[7]; 

    $url = encodeAttribute($url); 

    $result = "<a href=\"$url\""; 
    if (isset($title)) { 
     $title = encodeAttribute($title); 
     $result .= " title=\"$title\""; 
    } 

    $result .= ">$link_text</a>"; 

    return $result; 
} 

function encodeAttribute($text) { 
# 
# Encode text for a double-quoted HTML attribute. This function 
# is *not* suitable for attributes enclosed in single quotes. 
# 
    $text = encodeAmpsAndAngles($text); 
    $text = str_replace('"', '&quot;', $text); 
    return $text; 
} 

function encodeAmpsAndAngles($text) { 

    global $no_entities; 

# 
# Smart processing for ampersands and angle brackets that need to 
# be encoded. Valid character entities are left alone unless the 
# no-entities mode is set. 
# 
    if ($no_entities) { 
     $text = str_replace('&', '&amp;', $text); 
    } else { 
     # Ampersand-encoding based entirely on Nat Irons's Amputator 
     # MT plugin: <http://bumppo.net/projects/amputator/> 
     $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', 
          '&amp;', $text);; 
    } 
    # Encode remaining <'s 
    $text = str_replace('<', '&lt;', $text); 

    return $text; 
} 

function MarkdownUrl($text) { 

    global $nested_brackets_depth, $nested_url_parenthesis_depth; 

    $nested_brackets_re = 
      str_repeat('(?>[^\[\]]+|\[', $nested_brackets_depth). 
      str_repeat('\])*', $nested_brackets_depth); 

    $nested_url_parenthesis_re = 
      str_repeat('(?>[^()\s]+|\(', $nested_url_parenthesis_depth). 
      str_repeat('(?>\)))*', $nested_url_parenthesis_depth); 

    $text = preg_replace_callback('{ 
     (    # wrap whole match in $1 
      \[ 
      ('.$nested_brackets_re.') # link text = $2 
      \] 
      \(   # literal paren 
      [ \n]* 
      (?: 
       <(.+?)> # href = $3 
      | 
       ('.$nested_url_parenthesis_re.') # href = $4 
      ) 
      [ \n]* 
      (   # $5 
       ([\'"]) # quote char = $6 
       (.*?)  # Title = $7 
       \6  # matching quote 
       [ \n]* # ignore any spaces/tabs between closing quote and) 
      )?   # title is optional 
      \) 
     ) 
     }xs','doAnchors_inline_callback', $text); 

    return $text; 
} 

?> 

回答

1

那是因爲你有你的情況下,不同的變量的作用域。

在第一種情況下你的變量是在全球範圍內定義,從而$nested_brackets_depth = 6;MarkdownUrl.php規定的其他增值經銷商是可見的降價功能

在其他情況下 - 即變量函數,它包含文件範圍內定義的,所以它們在函數內部不可見。

解決辦法:改變降價文件頭

global $nested_brackets_depth = 6; 
global $nested_url_parenthesis_depth = 4; 
global $no_entities = false; 

順便說一句,這是一個很大的樣品,爲什麼global是邪惡的,爲什麼定義/在全球範圍內訪問變量是邪惡的了。

+0

當然!那麼,稍作改動(插入'global $ nested_brackets_depth,$ nested_url_parenthesis_depth,$ no_entities;'而不是嘗試初始化'global'聲明中的值)。 – mutus

+0

此外,如果我把它封裝在一個類中,而不是懶惰地將它們整合到程序代碼中,這可能是可以避免的。 – mutus

相關問題