成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

自己動(dòng)手寫PHP框架(二)

April / 2952人閱讀

摘要:作者上一篇提到了類的自動(dòng)加載和,今天就來(lái)逐一說(shuō)說(shuō)。為這個(gè)問(wèn)題提供了一個(gè)解決方案,這就是類的自動(dòng)裝載機(jī)制。為了方便使用自定義的全局,把方法也重寫了。

作者:Terry Gao

上一篇提到了類的自動(dòng)加載和Session,今天就來(lái)逐一說(shuō)說(shuō)。

1. 類的自動(dòng)加載

在使用PHP的OO模式開發(fā)系統(tǒng)時(shí),通常大家習(xí)慣將每個(gè)類的實(shí)現(xiàn)都存放在一個(gè)多帶帶的文件里,這樣會(huì)很容易實(shí)現(xiàn)對(duì)類進(jìn)行復(fù)用,同時(shí)將來(lái)維護(hù)時(shí)也很便利,這也是OO設(shè)計(jì)的基本思想之一。如果需要使用一個(gè)類,只需要直接使用include/require將其包含進(jìn)來(lái)即可。但隨著項(xiàng)目規(guī)模的不斷擴(kuò)大,使用這種方式會(huì)帶來(lái)一些隱含的問(wèn)題:如果一個(gè)PHP文件需要使用很多其它類,那么就需要很多的require/include語(yǔ)句,這樣有可能會(huì)造成遺漏或者包含進(jìn)不必要的類文件。如果大量的文件都需要使用其它的類,那么要保證每個(gè)文件都包含正確的類文件肯定是一個(gè)噩夢(mèng)。
PHP5為這個(gè)問(wèn)題提供了一個(gè)解決方案,這就是類的自動(dòng)裝載(autoload)機(jī)制。

/* NovaFrameworkAutoloader.php */
import()注冊(cè)到sql_autoload,作為本項(xiàng)目中類的自動(dòng)加載方法
        spl_autoload_register(array(
            $this,
            "import"
        ));
    }

    /**
     * Autoloader的入口函數(shù)
     * 用于創(chuàng)建Autoloader的唯一實(shí)例化對(duì)象
     *
     * @return Autoloader
     */
    public static function init()
    {
        if (self::$loader == NULL)
            self::$loader = new self();

        return self::$loader;
    }

    /**
     * 類的自動(dòng)加載方法
     * 根據(jù)傳入?yún)?shù)$className,自動(dòng)引入相應(yīng)類的源文件
     *
     * @param string $className
     */
    public function import($className)
    {
        $path = explode("", substr($className, strlen("Nova")));
        $filePath = ROOT_DIR . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $path) . ".php";
        if (is_file($filePath)) {
            require $filePath;
        }
    }
}

這個(gè)自動(dòng)加載類比較簡(jiǎn)單,初始化后,只有一個(gè)主要的方法import(),它通過(guò)解析傳入進(jìn)來(lái)的類名(由于我們使用了命名空間,所以類名基本上都是“NovaFrameworkAutoloader這樣的形式”),從項(xiàng)目根目錄開始,按照類名本身指定的路徑來(lái)定位相應(yīng)類的源碼文件,如果存在該文件,則將其引入。

更多關(guān)于自動(dòng)加載類的機(jī)制和原理,可以參考PHP autoload原理

2. Session

默認(rèn)情況下,PHP是將session以文件的形式存在服務(wù)器上,具體可以在php.ini中配置。但是實(shí)際生產(chǎn)環(huán)境中,稍大些的站點(diǎn)都不會(huì)采用這種形式,一般都會(huì)借助sql數(shù)據(jù)庫(kù)、或者nosql類型的如memcached、redis等緩存服務(wù)器來(lái)存儲(chǔ)session,這樣做可以有效緩解PHP服務(wù)器的壓力和處理速度,提高并發(fā)能力。

在Nova中我們使用redis服務(wù)器來(lái)存取Session。

/* NovaFrameworkSession.php
get(self::$sessionId, SESSION_TABLE_NAME);
        if ($sessionValue) {
            $_SESSION = $sessionValue;
        }
        return true;
    }

    /**
     * 將Session變量的內(nèi)容寫入Redis中
     *
     * @return bool
     */
    public static function write()
    {
        if (!empty($_SESSION)) {
            self::$redisCache->set(self::$sessionId, $_SESSION, SESSION_TABLE_NAME, SESSION_TIMEOUT);
        }
        return true;
    }

    /**
     * 通過(guò)刪除Redis中SessionId對(duì)應(yīng)的數(shù)據(jù)來(lái)注銷Session
     * session_destory()是自動(dòng)調(diào)用
     *
     * @return bool
     */
    public static function destory()
    {
        if (self::$redisCache->exists(self::$sessionId, SESSION_TABLE_NAME)) {
            self::$redisCache->delete(self::$sessionId, SESSION_TABLE_NAME);
        }
        setcookie(SESSION_NAME, self::$sessionId, 1, COOKIE_PATH, COOKIE_DOMAIN, FALSE);
        return true;
    }

    public static function close()
    {
        return true;
    }

    public static function gc()
    {
        return true;
    }

    /**
     * 返回一個(gè)SessionId
     * 若Cookie中已存在SessionId,則直接返回該SessionId
     * 若不存在,則按照規(guī)則新生成一個(gè)SessionId
     *
     * @return string Session Id
     */
    public static function get_sid()
    {
        self::$userIp = Tools::real_ip();
        $arr = $_COOKIE;
        //判斷Cookie中是否已經(jīng)存在SessionId
        if (is_null(self::$sessionId) && empty($arr[SESSION_NAME])) {
            //使用MD5對(duì)用戶IP+隨機(jī)字符串加密后作為新的SessionId
            self::$sessionId = function_exists("com_create_guid") ?
                md5(self::$userIp . com_create_guid()) : md5(self::$userIp . uniqid(mt_rand(), true));
            //對(duì)新的SessionId再做一次crc32運(yùn)算,作為最終的SessionId
            self::$sessionId .= sprintf("%08x", crc32(self::$sessionId));
            //將SessionId寫入Cookie中
            setcookie(SESSION_NAME, self::$sessionId, time() + SESSION_TIMEOUT, COOKIE_PATH, COOKIE_DOMAIN, FALSE);
            $_COOKIE[SESSION_NAME] = self::$sessionId;
        } else {
            self::$sessionId = $arr[SESSION_NAME];
        }
        //返回SessionId
        return self::$sessionId;
    }

}

Nova基本上重寫了Session的一些核心處理函數(shù)。為了方便使用自定義的全局Redis Rootkey,Nova把Redis方法也重寫了。

_redis = new Redis();
        $this->_redis->connect(REDIS_HOST, REDIS_PORT);
    }

    public static function get_instance($redisKey = REDIS_ROOT)
    {
        if (!(self::$_instanceObj[$redisKey] instanceof self)) {
            self::$_instanceObj[$redisKey] = new self;
        }

        self::$_instanceObj[$redisKey]->redisKey = $redisKey;
        return self::$_instanceObj[$redisKey];
    }

    public function set_group($groupName = "")
    {
        if (empty($groupName)) {
            return FLASE;
        }
        $this->groupName = $groupName;
        $this->groupPath = implode(":", explode("/", $groupName)) . ":";

        return TRUE;
    }

    public function set($key, $data, $groupName = "", $timeout = SESSION_TIMEOUT)
    {
        if (empty($groupName)) {
            $groupName = $this->groupName . $this->tempName;
        } else {
            $groupName = $this->groupName . $groupName;
        }

        if (is_array($data)) {
            $data = json_encode($data);
        }
        $redisKey = $groupName . $key;

        return $this->_redis->setex($redisKey, $timeout, $data);

    }

    public function get($key, $groupName = "")
    {
        if (empty($groupName)) {
            $groupName = $this->groupName . $this->tempName;
        } else {
            $groupName = $this->groupName . $groupName;
        }
        $redisKey = $groupName . $key;
        $return = "";
        $temp = $this->_redis->get($redisKey);
        $return = json_decode($temp, 1);
        return empty($return) ? $temp : $return;
    }

    public function delete($key, $groupName = "")
    {
        if (empty($groupName)) {
            $groupName = $this->groupName . $this->tempName;
        } else {
            $groupName = $this->groupName . $groupName;
        }
        $redisKey = $groupName . $key;
        return $this->_redis->delete($redisKey);
    }

    public function exists($key, $groupName = "")
    {
        if (empty($groupName)) {
            $groupName = $this->groupName . $this->tempName;
        } else {
            $groupName = $this->groupName . $groupName;
        }
        $redisKey = $groupName . $key;
        return $this->_redis->exists($redisKey);
    }
}

你可以在Github上查看Nova項(xiàng)目的源代碼。

如果你有任何問(wèn)題或建議,可以掃描下方二維碼或者微信搜索[phpjiagoushier],關(guān)注我的微信公眾號(hào)[PHP架構(gòu)],與我交流互動(dòng)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/22554.html

相關(guān)文章

  • 自己動(dòng)手PHP框架(一)

    摘要:作者作為的入門進(jìn)階,自己動(dòng)手寫一個(gè)框架可以從各方面鞏固和加深你對(duì)的理解,還能了解一些架構(gòu)方面的基礎(chǔ)知識(shí)。它將程序劃分為三層。最上面的一層,是直接面向最終用戶的視圖層。最底下的一層,是核心的模型層,負(fù)責(zé)檢索組織和處理程序所需的數(shù)據(jù)或信息。 作者:Terry Gao 作為PHP Coder的入門進(jìn)階,自己動(dòng)手寫一個(gè)MVC框架可以從各方面鞏固和加深你對(duì)PHP的理解,還能了解一些架構(gòu)方面的基礎(chǔ)...

    B0B0 評(píng)論0 收藏0
  • 自己動(dòng)手PHP框架(三)

    摘要:假設(shè)我們站點(diǎn)的域名是,用戶請(qǐng)求地址。模型層我們可以將數(shù)據(jù)組織和處理邏輯放在模型層,這里封裝了數(shù)據(jù)庫(kù)操作,甚至有些大型的框架會(huì)在這一層對(duì)這個(gè)數(shù)據(jù)庫(kù)進(jìn)行對(duì)象化,目的都是為了組織和處理數(shù)據(jù),然后將處理好的數(shù)據(jù)返回給控制器層。 作者:Terry Gao 1. 控制器 第一篇我們聊到路由分發(fā)會(huì)把用戶請(qǐng)求按照規(guī)則分發(fā)到控制器層的不同類,而默認(rèn)的規(guī)則中,請(qǐng)求會(huì)下發(fā)到控制器的index類的main方法...

    Terry_Tai 評(píng)論0 收藏0
  • 從零開始搭建論壇(一):Web服務(wù)器與Web框架

    摘要:服務(wù)器通過(guò)協(xié)議與客戶端通信,因此也被稱為服務(wù)器。本文標(biāo)題為從零開始搭建論壇一服務(wù)器與框架本文鏈接為更多閱讀自己動(dòng)手開發(fā)網(wǎng)絡(luò)服務(wù)器一自己動(dòng)手開發(fā)網(wǎng)絡(luò)服務(wù)器二自己動(dòng)手開發(fā)網(wǎng)絡(luò)服務(wù)器三服務(wù)器網(wǎng)關(guān)接口實(shí)現(xiàn)原理分析最佳實(shí)踐指南應(yīng)用淺談框架編程簡(jiǎn)介 之前用 Django 做過(guò)一個(gè)小的站點(diǎn),感覺(jué)Django太過(guò)笨重,于是就準(zhǔn)備換一個(gè)比較輕量級(jí)的 Web 框架來(lái)玩玩。Web.py 作者已經(jīng)掛掉,項(xiàng)目好...

    dantezhao 評(píng)論0 收藏0
  • 一本關(guān)于 React.js 的小書

    摘要:因?yàn)楣ぷ髦幸恢痹谑褂?,也一直以?lái)想總結(jié)一下自己關(guān)于的一些知識(shí)經(jīng)驗(yàn)。于是把一些想法慢慢整理書寫下來(lái),做成一本開源免費(fèi)專業(yè)簡(jiǎn)單的入門級(jí)別的小書,提供給社區(qū)。本書的后續(xù)可能會(huì)做成視頻版本,敬請(qǐng)期待。本作品采用署名禁止演繹國(guó)際許可協(xié)議進(jìn)行許可 React.js 小書 本文作者:胡子大哈本文原文:React.js 小書 轉(zhuǎn)載請(qǐng)注明出處,保留原文鏈接以及作者信息 在線閱讀:http://huzi...

    Scorpion 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<