2012-07-11 34 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。

在我看来,这个功能不会暴露给用户级代码。在任何情况下,引用都是一个棘手的业务,并且根据您传递的内容的具体情况使其变得更加可选,从而使其变得更糟。

我的建议:不要完全使用引用。你只会遇到问题。