国产chinesehdxxxx野外,国产av无码专区亚洲av琪琪,播放男人添女人下边视频,成人国产精品一区二区免费看,chinese丰满人妻videos

Joomla 使用預(yù)編譯語(yǔ)句

2023-03-10 11:12 更新

在 Joomla 4 中, Joomla 數(shù)據(jù)庫(kù)查詢轉(zhuǎn)變?yōu)槭褂妙A(yù)編譯語(yǔ)句,本文旨在闡明我們這樣做的原因和方式。

為什么要使用預(yù)編譯語(yǔ)句(Prepared Statements)?

簡(jiǎn)單的來(lái)說(shuō),預(yù)編譯語(yǔ)句相比之前的字符串查詢語(yǔ)句將會(huì)有兩大優(yōu)勢(shì):

  • 更加的高效
  • 更加的安全

預(yù)編譯語(yǔ)句(Prepared Statements)是什么?

通常我們的一條sql在db接收到最終執(zhí)行完畢返回可以分為下面三個(gè)過(guò)程:

  • 詞法和語(yǔ)義解析
  • 優(yōu)化sql語(yǔ)句,制定執(zhí)行計(jì)劃
  • 執(zhí)行并返回結(jié)果

我們把這種普通語(yǔ)句稱作Immediate Statements。

但是很多情況,我們的一條sql語(yǔ)句可能會(huì)反復(fù)執(zhí)行,或者每次執(zhí)行的時(shí)候只有個(gè)別的值不同(比如query的where子句值不同,update的set子句值不同,insert的values值不同)。如果每次都需要經(jīng)過(guò)上面的詞法語(yǔ)義解析、語(yǔ)句優(yōu)化、制定執(zhí)行計(jì)劃等,則效率就明顯不行了。

所謂預(yù)編譯語(yǔ)句就是將這類語(yǔ)句中的值用占位符替代,可以視為將sql語(yǔ)句模板化或者說(shuō)參數(shù)化,一般稱這類語(yǔ)句叫Prepared Statements或者Parameterized Statements 。

預(yù)編譯語(yǔ)句的優(yōu)勢(shì)歸納為:一次編譯、多次運(yùn)行,省去了解析優(yōu)化等過(guò)程;此外預(yù)編譯語(yǔ)句能防止sql注入。

如何在Joomla中使用預(yù)編譯語(yǔ)句(Prepared Statements)?

joomla在底層的JDatabaseDriver類中已經(jīng)幫我們實(shí)現(xiàn)好了預(yù)編譯語(yǔ)句這項(xiàng)功能,開(kāi)發(fā)者只需要在寫查詢語(yǔ)句的時(shí)候調(diào)用即可。以下面的查詢語(yǔ)句為例:

正常的SQL語(yǔ)句寫法:

$query =$this->db->getQuery(true)
    ->select($this->db->quoteName(array('id','password')))
    ->from($this->db->quoteName('#__users'))
    ->where($this->db->quoteName('username') .'=' .$this->db->quote($credentials['username']));

 轉(zhuǎn)換為預(yù)編譯語(yǔ)句的SQL語(yǔ)句寫法:

$query =$this->db->getQuery(true)
    ->select($this->db->quoteName(array('id','password')))
    ->from($this->db->quoteName('#__users'))
    ->where($this->db->quoteName('username') .' = :username')
    ->bind(':username',$credentials['username']);

通過(guò)在where中使用占位符,在bind中進(jìn)行參數(shù)綁定就實(shí)現(xiàn)了預(yù)編譯的功能。另外,請(qǐng)注意最后的bind方法,在這里我們不再使用$db的quote(加引號(hào))的方法,因?yàn)閿?shù)據(jù)庫(kù)驅(qū)動(dòng)將自動(dòng)的幫我們加上。

Joomla中使用預(yù)編譯語(yǔ)句的一些說(shuō)明

 JDatabaseDriver 會(huì)對(duì)一些函數(shù)自動(dòng)使用預(yù)編譯語(yǔ)句,如 whereIn()和whereNotIn()方法將自動(dòng)的使用。

典型的代碼如下:

$query =$this->db->getQuery(true)
    ->select($this->db->quoteName(array('id, password')))
    ->from($this->db->quoteName('#__users'))
    ->whereIn($this->db->quoteName('id'), [ 1, 2, 3 ]);

 這個(gè)查詢將會(huì)轉(zhuǎn)換為預(yù)編譯語(yǔ)句的SQL如下:

SELECT
  `id`, `password`
FROM
  `#__users`
WHERE
  `id`IN (
    :preparedArray1,
    :preparedArray2,
    :preparedArray3
  );

其中的占位符 :preparedArray1-3 將在執(zhí)行時(shí)填充 1,2,3。

通過(guò)在where中使用占位符,在bind中進(jìn)行參數(shù)綁定就實(shí)現(xiàn)了預(yù)編譯的功能。另外,請(qǐng)注意最后的bind方法,在這里我們不再使用$db的quote(加引號(hào))的方法,因?yàn)閿?shù)據(jù)庫(kù)驅(qū)動(dòng)將自動(dòng)的幫我們加上。

另外,以下函數(shù)接受數(shù)組以減少函數(shù)調(diào)用開(kāi)銷

  • bind()
  • bindArray()
  • whereIn()
  • whereNotIn()

另外在編程中使用預(yù)編譯的一個(gè)好處是可以方便的使用循環(huán),下面是一段實(shí)例代碼:

$listOfUsernames = ['admin','user1' ];
 
$query =$this->db->getQuery(true)
    ->select($this->db->quoteName(array('id','password')))
    ->from($this->db->quoteName('#__users'))
    ->where($this->db->quoteName('username') .' = :username')
    ->bind(':username',$username);
 
foreach($listOfUsernames as $name)
{
  $username =$name;
  $this->db->setQuery($query);
  $user =$this->db->loadObject();
  print_r($user);
}

在上面的循環(huán)中,給$username賦值,然后重新調(diào)用setQuery方法來(lái)獲得數(shù)據(jù),非常的方便。

同樣,也可以使用數(shù)據(jù)組來(lái)完成參數(shù)的綁定,代碼如下:

$query =$this->db->getQuery(true)
    ->select($this->db->quoteName(array('id','password')))
    ->from($this->db->quoteName('#__users'))
    ->where($this->db->quoteName('username') .' = :username')
    ->where($this->db->quoteName('id') .' = :id')
    ->bind([':username',':id'], [$credentials['username'], 42], [Joomla\Database\ParameterType::STRING, Joomla\Database\ParameterType::INTEGER]);

在上面的代碼中添加 username 和 id 作為綁定參數(shù),并為每個(gè)變量設(shè)置正確的 ParameterType。也可以對(duì)所有綁定值和 ParameterType 使用一個(gè)變量。 代碼如下:

$query =$this->db->getQuery(true)
    ->select($this->db->quoteName(array('id','password')))
    ->from($this->db->quoteName('#__users'))
    ->where($this->db->quoteName('username') .' = :username')
    ->where($this->db->quoteName('password') .' = :password')
    ->bind([':username',':password], $credentials['username']);

 在上面參數(shù) :username 和 :password 設(shè)置為相同的值和默認(rèn)的參數(shù)類型。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)