韩剧1988免费观看全集_久久影视三级福利片_亚洲视频在线观看免费_在线观看欧美日韩_国产亚洲激情在线_亚洲精品美女久久久_欧美国产日韩一区二区在线观看_91在线观看免费高清完整版在线观看_日韩av免费看_国产又爽又黄的激情精品视频_琪琪亚洲精品午夜在线_欧美性猛xxx_不卡毛片在线看_国产亚洲日本欧美韩国_91国内在线视频_精品国产福利视频

當前位置:蘿卜系統(tǒng)下載站 > 技術(shù)開發(fā)教程 > 詳細頁面

超過模板引擎

超過模板引擎

更新時間:2022-10-15 文章作者:未知 信息來源:網(wǎng)絡 閱讀次數(shù):

總體來說,模板引擎是一個"好東西"

作為一個PHP/Perl的程序員,許多模板引擎(fastTemplate, Smarty, Perl的 HTML::Template)的用戶,以及我自己的(bTemplate [1] 的作者),我講這句話很多次了。

然而,在同事進行了長時間的討論之后,我確信了大量的模板引擎(包括我自己寫的)根本是錯誤的。 我想唯一的例外是Smarty [2],雖然我認為它太龐大了,并且考慮到這篇文章的其余部分相當?shù)臎]有觀點。然而,就你為什么選擇Smarty(或者類似的解決方案)有幾個理由,這些將在文章后面探究。

這篇文章討論模板的理論。我們將看到為什么大部分"模板引擎"是過于肥大,并且最終我們將回過頭來看一個輕量級的,小巧快速的另類選擇。



下載和授權(quán)
模板類和所有在本文中使用的例子能夠在這里下載:template.zip [3]。你可以根據(jù)發(fā)布 [4]在 OSI [5] 的 MIT Open Source License使用這些文件中的代碼。



一些關(guān)于模板引擎的背景知識
讓我們首先研究一下模板引擎的背景知識。模板引擎被設計出來用于把商業(yè)邏輯(例如從數(shù)據(jù)庫中獲取數(shù)據(jù)或者計算貿(mào)易耗費)從數(shù)據(jù)的表現(xiàn)分離開來。模板引擎解決了兩個主要問題:


如何實現(xiàn)這種分離
如何從HTML中分離"復雜"的php代碼

這從理論上使得沒有PHP經(jīng)驗的HTML設計者能夠不看任何PHP代碼的條件下修改站點的外觀。

然而,模板系統(tǒng)也引入了一些復雜性。首先,我們現(xiàn)在有一個從多個文件得來的"頁面"。典型的,你可能有一個主PHP頁負責業(yè)務邏輯,一個外面的"布局"模板把整個站點的整體布局進行渲染,一個內(nèi)部的內(nèi)容特定的模板,一個數(shù)據(jù)庫抽象層,以及模板引擎本身(這些可能是也可能不是由多個文件組成)。也有可能,一些人僅僅簡單地在每個PHP頁面的首尾處包含"頭部"和"尾部"文件。

這產(chǎn)生的單個頁面的文件數(shù)量是很可觀的。然而,因為PHP解析器非?,用到的文件數(shù)量可能不是那么重要除非你的站點流量很大。
然而,要記住模板系統(tǒng)引入了另外一個處理的層次。模板文件不僅僅是必須被包含,他們還必須被解析(取決于模板系統(tǒng),這個行為有很多種方式來完成 —— 使用正則表達式,字符串替換,編譯,詞法分析,等等)。這就是為什么對模板進行測速變得流行起來:因為模板引擎使用各種方法來解析數(shù)據(jù),它們中的一些比另外一些要快(而且,一些模板引擎提供了比其他引擎更加豐富的功能)。



模板引擎基礎(chǔ)知識
簡單地說,模板引擎利用了用C寫的腳本語言(PHP)。在這些嵌入的腳本語言中,你有另外一個偽腳本語言(無論你的模板引擎支持何種標簽)。某些提供了簡單的變量改寫和循環(huán)。另外一些呢,則提供了條件和嵌套循環(huán)。而再其他的呢(至少有Smarty)提供了一個PHP的比較大的子集的接口,以及一個緩沖層。

為什么我認為Smarty最接近于正確的方向?因為Smarty的目標是"把業(yè)務邏輯從表現(xiàn)中分離出來"而不是"PHP代碼和HTML代碼的分離"。這看上去區(qū)別不大,但是它正是要點所在。任何模板引擎的最終目標不應該是從HTML移除所有的邏輯。它應該是把表現(xiàn)邏輯從業(yè)務邏輯中分離出來。

有很多你僅僅需要邏輯來正確顯示你的數(shù)據(jù)的例子。例如,你的業(yè)務邏輯是從你的數(shù)據(jù)庫中獲取一個用戶列表。你的表現(xiàn)邏輯可能是把用戶列表用3列顯示?赡苄薷挠脩袅斜砗瘮(shù)使得它返回3個數(shù)組是很笨的辦法。畢竟函數(shù)不應該關(guān)心數(shù)據(jù)接下來要怎么處理這樣的事情。然而,在你的模板文件中缺少一些邏輯,那些正是你要做的事情。

在這點上Smarty是正確的(使得你利用PHP的很多東西),但是仍然有許多問題;旧,它僅僅提供了一個以新語法訪問PHP的接口。以那開始,它看上去不那么聰明了。是不是事實上寫 {foreach --args} 比 <? foreach --args ?> 更加簡單?如果你認為這樣簡單一些,問問你自己是不是在包含一個巨大的模板庫來到成這種分離時能夠看到真正的意義要更加簡單一些。誠然,Smarty提供了許多其他很好的特性,但是看上去這些益處能夠在不用承擔包含Smarty類庫的情況下也能獲得。



別樣的解決方案
我主要要鼓吹的一個解決方案是一個使用PHP代碼作為它的原生腳本語言的"模板引擎"。我知道這以前有人做過。而且當我第一次看到的時候,我想,"為什么要這樣做?",然而我在考慮過我同事的論據(jù)之后,并且實現(xiàn)了一個直接使用PHP代碼仍然實現(xiàn)了把業(yè)務邏輯和表現(xiàn)邏輯分離的最終目標的模板系統(tǒng)時(只用了大約25行代碼,不包括注釋),我意識到了好處所在。

這個系統(tǒng)給像我們這樣的開發(fā)者提供了對PHP核心函數(shù)的訪問權(quán)利,我們能夠使用他們來格式化輸出——像日期格式化這樣的任務應該在模板中處理。而且,因為模板是普通的PHP文件,像Zend Performance Suite [6] 和PHP Accelerator [7] 這樣的字節(jié)碼緩存程序,能夠自動緩存模板(因而,它們不需要在每次被訪問時都被重新解釋執(zhí)行)。只要你記得把你的模板文件命名為程序能夠辨認出是PHP文件的名字(通常,你僅僅需要確保它們有一個.php的后綴),這確實是一個好處。

當我認為這種方法比經(jīng)典的模板引擎要高明得多時,肯定還有一些要商榷的問題。最明顯的反面意見是,PHP代碼太復雜了,而且設計者不應該強迫去學習PHP。事實上,PHP代碼和像Smarty這樣的高級模板引擎的語法差不多簡單(如果不是更簡單的話)。而且,設計者能夠使用像<?=$var;?>這樣的簡寫PHP。這要比{$var}復雜很多?當然,這要長一些,但是如果你習慣了,你能夠獲得了PHP的威力而且不用承受解析模板文件帶來的負擔。
第二,而且可能更重要的,在基于PHP的模板中沒有固有的安全。Smarty提供了選項在模板文件中徹底禁用PHP代碼。它使得開發(fā)者能夠約束模板能夠訪問的函數(shù)和變量。如果你沒有不懷好意的設計者,這不會是什么問題。然而,如果你允許外部的用戶上傳或者修改模板,我在此展示的基于PHP的解決方案絕對沒有任何安全可言!任何代碼都能放入模板中并且得到運行。是的,甚至是一個print_r($GLOBALS)(這將改有惡意的用戶訪問腳本中任何變量的權(quán)利)。

但是,我個人或者工作上寫過的項目中,絕大多數(shù)不允許最終的用戶修改或者上傳模板。如果是這樣,問題就不存在了。因此現(xiàn)在讓我們來看看代碼吧。



例子
這是一個簡單的用戶列表頁面的例子。

<?php
require_once('template.php');

/**
* This variable holds the file system path to all our template files.
*/
$path = './templates/';

/**
* Create a template object for the outer template and set its variables.
*/
$tpl = & new Template($path);
$tpl->set('title', 'User List');

/**
* Create a template object for the inner template and set its variables. The
* fetch_user_list() function simply returns an array of users.
*/
$body = & new Template($path);
$body->set('user_list', fetch_user_list());

/**
* Set the fetched template of the inner template to the 'body' variable in
* the outer template.
*/
$tpl->set('body', $body->fetch('user_list.tpl.php'));

/**
* Echo the results.
*/
echo $tpl->fetch('index.tpl.php');
?>
其中有兩個值得注意的重要的概念。第一個就是內(nèi)部和外部模板的概念。外部模板包含定義站點主要外觀的HTML代碼。而內(nèi)部模板包含定義站點內(nèi)容區(qū)域的HTML代碼。當然,你能夠在任意數(shù)目的層上有任意數(shù)目的模板。因為通常我們給每個區(qū)域使用不同的模板對象,所以沒有名字空間的問題。例如,我能在內(nèi)部和外部模板中都有變量叫"title",而不用害怕有什么沖突。

這是一個用來顯示用戶列表的模板的簡單例子。注意特殊的foreach和endforeach;語法在PHP手冊中有說明 [8]。它完全是可選擇的。

而且,你可能奇怪我為什么要用.php的后綴來命名我的模板文件。呵呵,許多PHP字節(jié)碼緩存解決方案(比如 phpAccelerator)如果要被認成PHP文件,需要文件有一個.php后綴。因為這些模板是PHP文件,為什么不去獲得這些好處?

<table>
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Banned</th>
</tr>
<? foreach($user_list as $user): ?>
<tr>
<td align="center"><?=$user['id'];?></td>
<td><?=$user['name'];?></td>
<td><a href="mailto:<?=$user['email'];?>"><?=$user['email'];?></a></td>
<td align="center"><?=($user['banned'] ? 'X' : '&nbsp;');?></td>
</tr>
<? endforeach; ?>


這個layout.tpl.php是一個簡單的例子(定義了整個頁面看上去是什么樣子的模板文件)
<html>
<head>
<title><?=$title;?></title>
</head>

<body>

<h2><?=$title;?></h2>

<?=$body;?>

</body>
</html>

而這是解析后的輸出。
<html>
<head>
<title>User List</title>
</head>

<body>

<h2>User List</h2>

<table>
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Banned</th>
</tr>
<tr>
<td align="center">1</td>
<td>bob</td>
<td><a href="mailto:bob@mozilla.org">bob@mozilla.org</a></td>
<td align="center">&nbsp;</td>
</tr>
<tr>
<td align="center">2</td>
<td>judy</td>
<td><a href="mailto:judy@php.net">judy@php.net</a></td>
<td align="center">&nbsp;</td>
</tr>
<tr>
<td align="center">3</td>
<td>joe</td>
<td><a href="mailto:joe@opera.com">joe@opera.com</a></td>
<td align="center">&nbsp;</td>
</tr>
<tr>
<td align="center">4</td>
<td>billy</td>
<td><a href="mailto:billy@wakeside.com">billy@wakeside.com</a></td>
<td align="center">X</td>
</tr>
<tr>
<td align="center">5</td>
<td>eileen</td>
<td><a href="mailto:eileen@slashdot.org">eileen@slashdot.org</a></td>
<td align="center">&nbsp;</td>
</tr>

</body>
</html>


緩存
因為解決方案簡單如斯,實現(xiàn)模板緩存成為了一個非常簡單的任務。為了實現(xiàn)緩存,我們有一個二級類,它擴展了原來的模板類。CachedTemplate類事實上使用和原來的模板類相同的API。不同點是我們必須傳遞緩存的設置給構(gòu)造函數(shù),并且調(diào)用fetch_cache()而不是fetch()。

緩存的概念是簡單的。簡單的說,我們設置一個緩存時間來調(diào)表輸出應該被保存的時長(以秒為單位)。在產(chǎn)生一個頁面的所有工作開展之前,我們必須首先測試頁面是否已經(jīng)被緩存了,而且緩存是否仍然沒有過期。如果緩存在這那,我們不需要在去麻煩數(shù)據(jù)庫和業(yè)務邏輯來產(chǎn)生頁面——我們可以簡單地輸出原先緩存地內(nèi)容。

這種方法需要解決唯一地標識緩存文件的問題。如果一個站點是被一個顯示基于GET變量的中心腳本所控制,對每個PHP文件只有一個緩存不會有什么幫助。例如,如果index.php?page=about_us和用戶調(diào)用index.php?page=contact_us得到的顯示完全不同。

問題是通過給每個頁面產(chǎn)生一個唯一的cache_id來解決的。為了做到這個目的,我們把事實上被請求的文件變成REQUEST_URI(基本上就是整個URL:index.php?foo=bar&bar=foo)。當然,這個轉(zhuǎn)換過程是受到CachedTemplate類控制的,但是要記住的重要的事情是你絕對要在創(chuàng)建CachedTemplate對象時傳遞一個唯一的cache_id。當然下面有例子來說明。

使用緩存包括以下步驟。


include() 模板源文件


創(chuàng)建一個新的CachedTemplate對象(并且傳遞路徑,唯一的cache_id和緩存過期時間給模板)


測試內(nèi)容是否已經(jīng)被緩存了


如果還促拿了,顯示文件并且結(jié)束腳本


否則,進行所有的處理并且fetch()模板


對fetch_cache()的調(diào)用將自動產(chǎn)生一個新的緩存文件

這個腳本假定你的緩存文件將放到./cache/中,因此你必須創(chuàng)建那個目錄并且改變它的目錄權(quán)限(chmod)使得Web服務器能夠?qū)懭胛募。而且還要注意如果你在編寫腳本的過程中發(fā)現(xiàn)了錯誤,錯誤也會被緩存!因而在你開發(fā)的過程中禁用緩存是一個好主意。最好的辦法是給cache的生存周期傳遞0——這樣,緩存總是立即就失效了。

這是一個實際的緩存的例子。

<?php
/**
* Example of cached template usage. Doesn't provide any speed increase since
* we're not getting information from multiple files or a database, but it
* introduces how the is_cached() method works.
*/

/**
* First, include the template class.
*/
require_once('template.php');

/**
* Here is the path to the templates.
*/
$path = './templates/';

/**
* Define the template file we will be using for this page.
*/
$file = 'list.tpl.php';

/**
* Pass a unique string for the template we want to cache. The template
* file name + the server REQUEST_URI is a good choice because:
* 1. If you pass just the file name, re-used templates will all
* get the same cache. This is not the desired behavior.
* 2. If you just pass the REQUEST_URI, and if you are using multiple
* templates per page, the templates, even though they are completely
* different, will share a cache file (the cache file names are based
* on the passed-in cache_id.
*/
$cache_id = $file . $_SERVER['REQUEST_URI'];
$tpl = & new CachedTemplate($path, $cache_id, 900);

/**
* Test to see if the template has been cached. If it has, we don't
* need to do any processing. Thus, if you put a lot of db calls in
* here (or file reads, or anything processor/disk/db intensive), you
* will significantly cut the amount of time it takes for a page to
* process.
*
* This should be read aloud as "If NOT Is_Cached"
*/
if(!($tpl->is_cached())) {
$tpl->set('title', 'My Title');
$tpl->set('intro', 'The intro paragraph.');
$tpl->set('list', array('cat', 'dog', 'mouse'));
}

/**
* Fetch the cached template. It doesn't matter if is_cached() succeeds
* or fails - fetch_cache() will fetch a cache if it exists, but if not,
* it will parse and return the template as usual (and make a cache for
* next time).
*/
echo $tpl->fetch_cache($file);
?>


設置多個變量
我們?nèi)绾文軌蛲瑫r設置多個變量?這又一個使用由Ricardo Garcia貢獻的函數(shù)的例子。

<?php
require_once('template.php');

$tpl = & new Template('./templates/');
$tpl->set('title', 'User Profile');

$profile = array(
'name' => 'Frank',
'email' => 'frank@bob.com',
'password' => 'ultra_secret'
);

$tpl->set_vars($profile);

echo $tpl->fetch('profile.tpl.php');
?>
相關(guān)的模板是這樣的:

<table cellpadding="3" border="0" cellspacing="1">
<tr>
<td>Name</td>
<td><?=$name;?></td>
</tr>
<tr>
<td>Email</td>
<td><?=$email;?></td>
</tr>
<tr>
<td>Password</td>
<td><?=$password;?></td>
</tr>

而且解析后的輸出是這樣的:

<table cellpadding="3" border="0" cellspacing="1">
<tr>
<td>Name</td>
<td>Frank</td>
</tr>
<tr>
<td>Email</td>
<td>frank@bob.com</td>
</tr>
<tr>
<td>Password</td>
<td>ultra_secret</td>
</tr>

特別感謝Ricardo Garcia和Harry Fuecks他們的對這篇文章的貢獻。



相關(guān)的鏈接
這兒是一個總體上探究模板引擎的好去處的列表。


Web Application Toolkit Template View [9] - 許多關(guān)于模板實現(xiàn)方法的信息
MVC Pattern [10] - 描述3層應用程序的設計
SimpleT [11] - 另一個使用PEAR::Cache_Lite的基于php的模板引擎
Templates and Template Engines [12] - 更多關(guān)于各種模板實現(xiàn)的信息
Smarty [13] - 編譯型模板引擎



模板類源代碼
以及最后出場的,模板類。

<?php
/**
* Copyright (c) 2003 Brian E. Lozier (brian@massassi.net)
*
* set_vars() method contributed by Ricardo Garcia (Thanks!)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

class Template {
var $vars; /// Holds all the template variables
var $path; /// Path to the templates

/**
* Constructor
*
* @param string $path the path to the templates
*
* @return void
*/
function Template($path = null) {
$this->path = $path;
$this->vars = array();
}

/**
* Set the path to the template files.
*
* @param string $path path to template files
*
* @return void
*/
function set_path($path) {
$this->path = $path;
}

/**
* Set a template variable.
*
* @param string $name name of the variable to set
* @param mixed $value the value of the variable
*
* @return void
*/
function set($name, $value) {
$this->vars[$name] = $value;
}

/**
* Set a bunch of variables at once using an associative array.
*
* @param array $vars array of vars to set
* @param bool $clear whether to completely overwrite the existing vars
*
* @return void
*/
function set_vars($vars, $clear = false) {
if($clear) {
$this->vars = $vars;
}
else {
if(is_array($vars)) $this->vars = array_merge($this->vars, $vars);
}
}

/**
* Open, parse, and return the template file.
*
* @param string string the template file name
*
* @return string
*/
function fetch($file) {
extract($this->vars); // Extract the vars to local namespace
ob_start(); // Start output buffering
include($this->path . $file); // Include the file
$contents = ob_get_contents(); // Get the contents of the buffer
ob_end_clean(); // End buffering and discard
return $contents; // Return the contents
}
}

/**
* An extension to Template that provides automatic caching of
* template contents.
*/
class CachedTemplate extends Template {
var $cache_id;
var $expire;
var $cached;

/**
* Constructor.
*
* @param string $path path to template files
* @param string $cache_id unique cache identifier
* @param int $expire number of seconds the cache will live
*
* @return void
*/
function CachedTemplate($path, $cache_id = null, $expire = 900) {
$this->Template($path);
$this->cache_id = $cache_id ? 'cache/' . md5($cache_id) : $cache_id;
$this->expire = $expire;
}

/**
* Test to see whether the currently loaded cache_id has a valid
* corrosponding cache file.
*
* @return bool
*/
function is_cached() {
if($this->cached) return true;

// Passed a cache_id?
if(!$this->cache_id) return false;

// Cache file exists?
if(!file_exists($this->cache_id)) return false;

// Can get the time of the file?
if(!($mtime = filemtime($this->cache_id))) return false;

// Cache expired?
if(($mtime + $this->expire) < time()) {
@unlink($this->cache_id);
return false;
}
else {
/**
* Cache the results of this is_cached() call. Why? So
* we don't have to double the overhead for each template.
* If we didn't cache, it would be hitting the file system
* twice as much (file_exists() & filemtime() [twice each]).
*/
$this->cached = true;
return true;
}
}

/**
* This function returns a cached copy of a template (if it exists),
* otherwise, it parses it as normal and caches the content.
*
* @param $file string the template file
*
* @return string
*/
function fetch_cache($file) {
if($this->is_cached()) {
$fp = @fopen($this->cache_id, 'r');
$contents = fread($fp, filesize($this->cache_id));
fclose($fp);
return $contents;
}
else {
$contents = $this->fetch($file);

// Write the cache
if($fp = @fopen($this->cache_id, 'w')) {
fwrite($fp, $contents);
fclose($fp);
}
else {
die('Unable to write cache.');
}

return $contents;
}
}
}
?>
另外一個值得注意的重要的事情是這里展示的解決辦法是我們傳遞模板的文件名給fetch()函數(shù)。如果你需要重用模板對象而不去re-set()所有的變量,這將比較有用。

并且記。耗0逡娴囊c是把你的業(yè)務邏輯從你的表現(xiàn)邏輯中分離出來,而不是把你的PHP代碼從HTML代碼中分離出來。

本文附件下載:template.zip [1] http://www.massassi.com/bTemplate/
[2] http://smarty.php.net/
[3] http://www.sitepoint.com/examples/tempeng/template.zip
[4] http://opensource.org/licenses/mit-license.html
[5] http://www.opensource.org/
[6] http://zend.com/store/products/zend-performance-suite.php
[7] http://www.php-accelerator.co.uk/
[8] http://www.php.net/manual/en/control-structures.alternative-syntax.php
[9] http://wact.sourceforge.net/index.php/TemplateView
[10] http://www.phppatterns.com/index.php/article/articleview/11/
[11] http://simplet.sourceforge.net/
[12] http://phppatterns.com/index.php/article/articleview/4/1/1/
[13] http://smarty.php.net/

本文英文原版地址:http://www.sitepoint.com/article/1218/

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統(tǒng)下載排行

網(wǎng)站地圖xml | 網(wǎng)站地圖html
韩国中文字幕在线| 午夜剧场高清版免费观看| 日本二区视频| 国产激情视频一区二区| 国产欧美在线一区二区| 中文字幕久久综合| 亚洲人成人一区二区三区| 国产日韩在线一区二区三区| av激情综合网| 欧美精品久久久久久久久久丰满| 第一社区sis001原创亚洲| 99精品视频在线免费播放| 中文字幕人成一区| 亚洲精品小视频| 亚洲国产91精品在线观看| 只有精品亚洲| 五级黄高潮片90分钟视频| 韩国av中国字幕| 中文字幕人成乱码在线观看| 女人色极品影院| 成人在线免费小视频| 国产一区二区三区91| 麻豆国产在线播放| 深夜福利免费在线观看| 国产精品99久久免费观看| 五月久久久综合一区二区小说| 亚洲欧美手机在线| 尤物yw午夜国产精品视频明星| 国产av熟女一区二区三区| 综合色婷婷一区二区亚洲欧美国产| 国产精品xx| 一本大道av伊人久久综合| 国产三级三级三级看三级| 欧美一区二区三区久久精品茉莉花| 杨幂一区欧美专区| 欧美熟妇另类久久久久久多毛| 男女无套免费视频网站动漫| heyzo欧美激情| 国产91久久婷婷一区二区| 欧美疯狂做受xxxx高潮| 国产午夜视频在线播放| 中文字幕五月天| 成人激情在线观看| 婷婷国产成人精品视频| 日本又骚又刺激的视频在线观看| av电影免费| 国产又爽又黄免费视频| 伦伦影院午夜理论片| 亚洲高清免费观看高清完整版在线观看| 狠狠色噜噜狠狠狠8888米奇| 日韩毛片久久久| 女人在下体塞跳蛋在线观看| 92久久精品| 小小的日本在线观看免费色网| www..com.cn蕾丝视频在线观看免费版| 成人黄色av网址| 日本欧美久久久久免费播放网| 欧美三级在线观看视频| 一本色道久久综合亚洲精品高清| 成人av色在线观看| 精品国产一区二区三区四| 亚洲黄色av网址| 欧美亚洲国产一区在线观看网站| 成人动漫网站在线观看| 69国产精品视频免费观看| 欧美日韩成人影院| 在线电影院国产精品| 在线欧美视频| 在线观看欧美一区二区| 欧美三级三级三级| 91亚洲精选| 国产精品色呦| 亚洲av成人精品一区二区三区在线播放| 另类国产精品一区二区| 成人影院天天5g天天爽无毒影院| 小舞被吸乳羞羞网站视频| 久久躁日日躁aaaaxxxx| 国产亚洲精久久久久久无码77777| 日韩av高清| 8888四色奇米在线观看| 黑人精品一区二区三区| 日本中文在线观看| 欧美自拍视频在线观看| 亚洲天堂成人在线观看| 亚洲图片欧美在线| 领导边摸边吃奶边做爽在线观看| 91中文在线视频| 日本韩国欧美国产| 91精品国产综合久久香蕉| caoporn97免费视频公开| 78精品国产综合久久香蕉| 日本不卡免费在线视频| 欧美视频不卡中文| 久久福利精品| 欧美日本高清| av中文字幕在线免费观看| 亚洲一区二区在线观看视频| 欧美成人免费全部| 午夜不卡久久精品无码免费| 人人妻人人玩人人澡人人爽| 国产精品久久成人免费观看| 亚洲综合在线中文字幕| 精品99999| 国产一区二区三区在线看麻豆| 成人高清在线观看| av免费在线观看网址| 麻豆国产欧美一区二区三区| 中文字幕日韩高清在线| 色婷婷亚洲精品| 跑男十一季在线观看免费| 欧美日韩成人高清| 青青青国产精品| 日本v片在线免费观看| 日本特级黄色片| 狠狠精品干练久久久无码中文字幕| 欧美男女视频| 中文字幕中文字幕在线中高清免费版| 一区二区三区四区免费视频| 亚洲精品影院在线观看| 久久青青草视频| 午夜av一区二区| 激情综合网址| 色欲人妻综合网| 日本免费一级视频| 久久影院朴妮唛| 日韩和的一区二在线| 91在线精品一区二区| 精品高清视频| 在线观看网站黄| 国产日本欧美在线| 国产中文第一页| 欧美性猛交bbbbb精品| 在线观看a视频| 日本免费网址| 欧美日本精品在线| av网站免费在线观看| 亚洲第一av在线| 一本之道在线视频| 无码任你躁久久久久久老妇| 国产成人亚洲欧美| 国产精品a成v人在线播放| av中文一区二区三区| 天堂在线www天堂中文在线| 久久6精品影院| 中文文字幕文字幕高清| 免费av在线网站| 蜜桃一区二区三区在线| 欧美高清性猛交| 中国特级黄色片| 日本在线视频1区| 日本黄视频网站| 国产福利精品av综合导导航| 最新av电影网站| 性生交免费视频| 97超碰人人在线| 一区二区三区国产豹纹内裤在线| 女女调教被c哭捆绑喷水百合| 欧美13~18sex性hd| 欧美午夜精品久久久久久蜜| 无码人妻久久一区二区三区蜜桃| 久草网在线视频| 国产经典久久久| 国产区一区二区三区| 欧美亚洲另类在线| 日韩精品在线免费看| 日本77777| 亚洲人成人77777线观看| 91免费看片| 亚洲一区二区三区| 亚洲经典视频在线观看| 国产精品久久久久福利| 欧美日韩三级| 亚洲欧美久久婷婷爱综合一区天堂| 亚洲乱码一区二区| 欧美中文字幕亚洲一区二区va在线| 日本少妇性高潮| 高清一区二区三区四区五区| av资源中文色综合| 一级毛片免费高清中文字幕久久网| 久久久成人的性感天堂| 亚洲免费网站观看视频| 久久久久久久黄色| 免费在线黄色网| 欧美日韩在线三区| 男人揉女人奶房视频60分| 奇米色在线视频| 香蕉综合视频| 一区二区三区视频免费视频观看网站| 三级毛片在线免费看| 黄色的视频在线观看免费| 呦呦在线视频| 午夜精品久久久久久| 不卡视频一二三四| 成人18夜夜网深夜福利网| 国产女人18毛片18精品| 91亚洲精品久久久蜜桃借种| 青丝免费观看高清影视| 久久国产免费观看| 97精品久久久午夜一区二区三区| eeuss鲁片一区二区三区| 亚洲深夜福利在线观看| 一区二区三区麻豆| 欧美视频免费在线观看| 日韩少妇内射免费播放| 欧美xxxxxxxxx59| 日本不卡一区二区在线观看| 亚洲一级黄色av| 毛片在线免费视频| av男人天堂av| 99蜜桃在线观看免费视频网站| 在线视频日韩| 亚洲日本japanese丝袜| 亚洲精品永久www嫩草| 成人性视频欧美一区二区三区| 亚洲电影在线免费观看| 小明成人免费视频一区| 色噜噜狠狠色综合中国| 亚洲精品成人久久久| 色www精品视频在线观看| 日本中文字幕免费在线观看| 国产精品视频免费一区二区三区| av大全在线| 国产精品有限公司| 精品无码久久久久久久久| 国产一级大片| 亚洲最大激情中文字幕| 久久久久影视| 天使と恶魔の榨精在线播放| 色男人天堂av| 久久久精品久久久| 国产xxxx视频| 日本女人性生活视频| 婷婷丁香激情综合| 欧美日韩一本到| 在线视频一二区| 男人天堂综合网| 性xxxfreexxxx性欧美| 欧美精品色综合| 久久综合网色—综合色88| h视频免费网站| 亚洲a∨精品一区二区三区导航| 高清国产一区二区三区四区五区| 嫩草影院一区二区| 国产三级精品三级在线| 99热这里只有精品在线播放| 另类尿喷潮videofree| 美女被到爽高潮视频| 熟女人妻在线视频| 欧美一二三四区在线| 日本视频三区| 99久久综合狠狠综合久久aⅴ| 97色在线播放视频| 日韩精品在线一区二区三区| αv一区二区三区| 欧美激情视频在线| 成人线上视频| 国产精品国码视频| 欧美视频一区二区三区在线观看| 色乱码一区二区三区网站| 亚州视频一区二区三区| 亚洲人成在线观看一区二区| 欧美肥婆姓交大片| 男男成人高潮片免费网站| 激情欧美一区二区三区在线观看| 亚洲国产精品高清| av午夜精品一区二区三区| 另类欧美视频| 在线成人直播| 一本色道久久综合亚洲精品高清| 91丨九色丨蝌蚪丨老板| 好男人免费精品视频| 免费不卡在线观看| 成人精品视频.| 免费人成网站在线观看欧美高清| 久久综合激情网| 国产偷国产偷精品高清尤物| 亚洲另类av| 一区二区中文字幕在线观看| 黄网在线观看| 亚洲综合色丁香婷婷六月图片| 夜色av.com| 欧美最近摘花xxxx摘花| 国产成人午夜精品影院观看视频| 欧美群妇大交群的观看方式| 偷拍自拍亚洲色图| www.中文字幕.com| 国产在线观看第一页| 久久无码av三级| 国产成人一区三区| 欧美成人免费va影院高清| 精品成人免费| 久久99国产精品一区| 国产精品久在线观看| 日韩一级欧洲| 亚洲小说区图片区| 草草视频在线播放| 精品视频在线观看免费观看| 国产亚洲自拍av| av网站网址在线观看| 8x8x最新地址| 国产福利小视频在线| 一级视频在线观看| 波多野结衣家庭教师视频| 日韩视频三区| 日本欧美在线视频免费观看| 性欧美.com| 国产激情一区二区三区在线观看| 国产熟女一区二区丰满| 亚洲视频久久久| 久久日韩视频| 国产情侣在线视频| 久久精品视频va| 国产精品夜夜夜一区二区三区尤| 色综合天天综合| 亚洲欧美在线视频| 精品调教chinesegay| 2018av| 成人av视屏| 久久综合久久99| www.成人69.com| eeuss影院www在线观看| 色妞色视频一区二区三区四区| 中日韩脚交footjobhd| 国产91在线视频| 欧美成人午夜| 欧美综合一区第一页| 激情五月宗合网| 国产视频网址在线|