4

在 Code Igniter 框架中有几个这种行为的例子——在方法的开头创建一个变量,使用它,在方法结束之前,取消设置这个变量。

他们为什么要取消它们?重点是什么?据我所知,局部变量无论如何都会在方法结束时消失。

来自会话类的代码点火器(见最后几行):

function sess_read()
{
    // Fetch the cookie
    $session = $this->CI->input->cookie($this->sess_cookie_name);

    // No cookie?  Goodbye cruel world!...
    if ($session === FALSE)
    {
        log_message('debug', 'A session cookie was not found.');
        return FALSE;
    }

    // Decrypt the cookie data
    if ($this->sess_encrypt_cookie == TRUE)
    {
        $session = $this->CI->encrypt->decode($session);
    }
    else
    {
        // encryption was not used, so we need to check the md5 hash
        $hash    = substr($session, strlen($session)-32); // get last 32 chars
        $session = substr($session, 0, strlen($session)-32);

        // Does the md5 hash match?  This is to prevent manipulation of session data in userspace
        if ($hash !==  md5($session.$this->encryption_key))
        {
            log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
            $this->sess_destroy();
            return FALSE;
        }
    }

    // Unserialize the session array
    $session = $this->_unserialize($session);

    // Is the session data we unserialized an array with the correct format?
    if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity']))
    {
        $this->sess_destroy();
        return FALSE;
    }

    // Is the session current?
    if (($session['last_activity'] + $this->sess_expiration) < $this->now)
    {
        $this->sess_destroy();
        return FALSE;
    }

    // Does the IP Match?
    if ($this->sess_match_ip == TRUE AND $session['ip_address'] != $this->CI->input->ip_address())
    {
        $this->sess_destroy();
        return FALSE;
    }

    // Does the User Agent Match?
    if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 120)))
    {
        $this->sess_destroy();
        return FALSE;
    }

    // Is there a corresponding session in the DB?
    if ($this->sess_use_database === TRUE)
    {
        $this->CI->db->where('session_id', $session['session_id']);

        if ($this->sess_match_ip == TRUE)
        {
            $this->CI->db->where('ip_address', $session['ip_address']);
        }

        if ($this->sess_match_useragent == TRUE)
        {
            $this->CI->db->where('user_agent', $session['user_agent']);
        }

        $query = $this->CI->db->get($this->sess_table_name);

        // No result?  Kill it!
        if ($query->num_rows() == 0)
        {
            $this->sess_destroy();
            return FALSE;
        }

        // Is there custom data?  If so, add it to the main session array
        $row = $query->row();
        if (isset($row->user_data) AND $row->user_data != '')
        {
            $custom_data = $this->_unserialize($row->user_data);

            if (is_array($custom_data))
            {
                foreach ($custom_data as $key => $val)
                {
                    $session[$key] = $val;
                }
            }
        }
    }

    // Session is valid!
    $this->userdata = $session;
    unset($session);

    return TRUE;
}
4

1 回答 1

6

unset()销毁指定的变量。但unset()不会释放 PHP 脚本消耗的内存,它会释放它以供 PHP 脚本本身使用。它不会强制立即释放内存。PHP 的垃圾收集器会在它认为合适的时候执行它 - 有意尽快,因为无论如何都不需要这些 CPU 周期,或者直到脚本耗尽内存之前,无论首先发生什么。

因此,如果您在循环中创建 10 次大小为 10M 的变量并在循环结束时取消设置(或重写)它,那么到循环结束时内存消耗应该低至 10M + 所有其他变量.

阅读更多

用 PHP 释放内存有什么好处:unset() 或 $var = null

为什么 UNSET 和 NULL 以不同的方式工作

于 2013-04-01T11:40:36.053 回答