2012-07-11 66 views
0

當你想僅在一些時間調用帶有byref參數的函數時,你會做什麼(在最近的PHP中)?聲明一個函數來獲取byref和byval參數

function blah_byval ($arg) { /* some code */ } 
function blah_byref (&$arg) { /* same code */ } 

好像阻礙我。我肯定錯過了什麼。

我確實有一個用例,雖然問題基本上是假設的。這裏有一個驗證碼實現的在建工程:

function captcha_image($string = "", $create = true, $session = "") { 

    # outputs a transparent gif image 16 pixels high by 60 pixels wide containing 
    # a string of six lowercase letters, either specified by $string or generated 
    # randomly. returns this string, or false in the event of an error. 

    # once a captcha image is created, the string it contains should be saved so 
    # that it can be compared later with user input. to skip saving, set $create 
    # to false. 

    # if called from a web server, content-type is set. 

    if (!preg_match("/^[a-z]{6}$/", $string)) $string = string_random(6); 
    if (php_sapi_name() != "cli") header("Content-Type: image/gif"); 
    if ($ihandle = @imagecreatetruecolor(60, 16)) { 
    $background = imagecolorallocate($ihandle, 255, 255, 255); 
    $foreground = imagecolorallocate($ihandle, 128, 128, 128); 
    imagecolortransparent($ihandle, $background); 
    imagefilledrectangle($ihandle, 0, 0, 60, 16, $background); 
    imagestring($ihandle, 5, 0, 0, $string, $foreground); 
    imagegif($ihandle, NULL); 
    imagedestroy($ihandle); 
    if ($create) return captcha_create($string, $session); 
    return $string; 
    } 
    return false; 
} 

function captcha_compare($string, $session = "", $destroy = true) { 

    # returns true if $string is associated with a certain session, which is 
    # specified by $session or, if no such session exists, by session_identity(). 
    # if $string is not associated with the session, returns false. 

    # once a string is matched to a session, it should be destroyed to prevent 
    # re-use. to allow re-use, $destroy may be set to false. 

    global $cfgimage; 
    if (!session_exists($session)) $session = session_identity(); 
    $get_return = false; 
    if ($chandle = @fopen($cfgimage['captcha']['file'], "rb")) { 
    flock($chandle, LOCK_SH); 
    while (!feof($chandle)) { 
     $line = explode(" ", trim(fgets($chandle)), 3); 
     if (($line[2] === $string) && ($line[1] == $session) && ($line[0] > (time() - $cfgimage['captcha']['keepalive']))) { 
     $get_return = true; 
     break; 
     } 
    } 
    fclose($chandle); 
    } 
    if (($destroy) && ($get_return)) captcha_destroy($session); 
    return $get_return; 
} 

function captcha_create($string, $session = "") { 

    # associates a string of six lowercase letters with a session, either 
    # specified by $session or by session_identity(). fails if $string is not 
    # well-formed. returns true if successful, or false. 

    global $cfgimage; 
    if (!preg_match("/^[a-z]{6}$/", $string)) return false; 
    if (!session_exists($session)) $session = session_identity(); 
    if ($thandle = @tmpfile()) { 
    if ($chandle = @fopen($cfgimage['captcha']['file'], "rb")) { 
     flock($chandle, LOCK_SH); 
     while (!feof($chandle)) { 
     $line = explode(" ", trim(fgets($chandle)), 3); 
     if (($line[1] != $session) && ($line[0] > (time() - $cfgimage['captcha']['keepalive']))) fputs($thandle, implode(" ", $line) . "\n"); 
     } 
     fclose($chandle); 
     fseek($thandle, 0); 
     if ($chandle = @fopen($cfgimage['captcha']['file'], "cb")) { 
     if (flock($chandle, LOCK_EX)) { 
      fputs($chandle, time() . " " . $session . " " . $string . "\n"); 
      while (!feof($thandle)) fputs($chandle, fgets($thandle)); 
     } 
     fclose($chandle); 
     } 
    } 
    flock($thandle, LOCK_UN); 
    fclose($thandle); 
    return true; 
    } 
    return false; 
} 

function captcha_destroy($session = "") { 

    # dis-associates any existing captcha string with a session, either specified 
    # by $session or by session_identity(). does not return any value. 

    global $cfgimage; 
    if (!session_exists($session)) $session = session_identity(); 
    if ($thandle = @tmpfile()) { 
    if ($chandle = @fopen($cfgimage['captcha']['file'], "rb")) { 
     flock($chandle, LOCK_SH); 
     while (!feof($chandle)) { 
     $line = explode(" ", trim(fgets($chandle)), 3); 
     if (($line[1] != $session) && ($line[0] > (time() - $cfgimage['captcha']['keepalive']))) fputs($thandle, implode(" ", $line) . "\n"); 
     } 
     fclose($chandle); 
     fseek($thandle, 0); 
     if ($chandle = @fopen($cfgimage['captcha']['file'], "cb")) { 
     if (flock($chandle, LOCK_EX)) { 
      while (!feof($thandle)) fputs($chandle, fgets($thandle)); 
     } 
     fclose($chandle); 
     } 
    } 
    flock($thandle, LOCK_UN); 
    fclose($thandle); 
    } 
} 

在captcha_image(),return captcha_create($string, $session)曾經是captcha_create(&$string ...)

+3

您不會編寫在不同時間需要兩種不同類型參數的代碼。 ':)' – nickb 2012-07-11 16:27:33

+0

PHP如何知道什麼時候該做什麼?反正它通常是一個壞主意,它有代碼味道恕我直言。 – PeeHaa 2012-07-11 16:27:40

+3

這個函數做什麼,你不想通過ref?如果你沒有更新參考文獻,我認爲它不重要。你可以通過第二個參數嗎? – 2012-07-11 16:28:21

回答

3

這在用戶級代碼中是不可能的。對於手頭的內部函數,您可以在arginfo結構中指定PREFER_REF標誌。如果可能的話,這將通過-ref傳遞值,否則通過by-val。

在我看來,這個功能不會暴露給用戶級代碼。在任何情況下,引用都是一個棘手的業務,並且根據您傳遞的內容的具體情況使其變得更加可選,從而使其變得更糟。

我的建議:不要完全使用引用。你只會遇到問題。