[英]Wordpress - Define Peramlink and call it within URLs within functions.php
[英]Define two functions, or branch within one?
我正在閱讀如何在PHP中檢測文件的編碼,在某些博客或某處,有人建議這樣做:
if (function_exists('mb_detect_encoding')) {
function is_utf8($str) {
// do stuff using the mb* libraries
}
} else {
function is_utf8($str) {
// do stuff manually
}
}
對我來說,這感覺非常混亂,可以用這個代替:
function is_utf8($str) {
if (...) {
// mb stuff here
} else {
// manual stuff here
}
}
但是,我也可以看到它也有一些好處。 根據if
語句的復雜程度以及調用函數的頻率,這可能會更有效。 我的問題是:你會在什么時候考慮將功能分成兩個,就像在第一個例子中一樣? 我錯過了其他任何利弊嗎?
編輯 :請不要掛在這里的例子,問題是關於這種做法一般。
我的直覺反應是使用is_utf8
函數的單個聲明。 PHP引擎非常擅長優化,並且多次調用function_exists()
的開銷應該可以忽略不計。
一個好的做法,也許不是那種情況,但通常可能涉及使用工廠方法的OOP(對象)。
class my_utf8
{
// A static method that determine what object to create
public static function factory() {
if (function_exists('mb_detect_encoding')) {
return new my_utf8_with_mb;
} else {
return new my_utf8_without_mb;
}
}
}
class my_utf8_with_mb extends my_utf8 {
public function is_utf8($str) {
// do stuff using the mb* libraries
}
}
class my_utf8_without_mb extends my_utf8 {
public function is_utf8($str) {
// do stuff without the mb* libraries
}
}
在您的申請中:
global $myUtfInstance;
// Call once
$myUtfInstance = my_utf8::factory();
// later and forever...
$myUtfInstance->is_utf8($str);
根據您的操作,您還可以使用單例模式。 它不會跳過IF,但不需要全局變量。
class my_utf8
{
private static $instance;
public static function factory() {
if (function_exists('mb_detect_encoding')) {
return new my_utf8_with_mb;
} else {
return new my_utf8_without_mb;
}
}
public static function getInstance()
{
if (!self::$instance) {
self::$instance = self::factory();
}
return self::$instance;
}
}
在你的代碼中:
my_utf8::getInstance()->is_utf8($str);
在風格上,我傾向於推動第二個。 如果性能是一個問題,那么你最好考慮使用第一個。
if (function_exists("sin")) { function baz($farfs) { print "I am the first baz"; } } else { function baz($farfs) { print "I am the second baz"; } } function blarg($fgar) { if (function_exists("sin")) { print "I am the first blarg"; } else { print "I am the second blarg"; } } for ($i=0;$i
我在我的工作站上運行了這個,發現調用baz的總時間占總調用的50-75%到blarg,這取決於被測試的函數是否確實存在。
以下是實際數字:
這兩個函數之間的唯一區別是條件和輸出中的兩個額外字符。 有趣的是,10001對function_exists的調用在兩次測試中分別只需要0.18和0.11 ms。 我想知道是否在某個配置文件中都沒有考慮到某些函數調用開銷。
至於風格,我真的不喜歡第一個。 在兩個不同的地方通過名稱定義函數似乎是一件很糟糕的事情,特別是當依賴於PHP中的奇怪性時,使得在全局范圍內不執行的函數定義無論如何都會影響全局范圍。 另一方面,我的偏見可能正在顯示,並且PHP社區的其余部分在這個實例中依賴PHP解釋器作為一種預處理器可能沒有問題。
聳聳肩這是風格問題。
默認情況下,始終使用最易讀的解決方案。 如果特定的代碼片段在您的應用程序中被證明是一個重要的阻力(測量,未假設),那么您將對其進行優化。
我會提前為最可能非常丑陋的PHP道歉,但我會做更多的事情:
if (function_exists('mb_detect_encoding')) {
function is_utf8_mb($str) {
// do stuff using the mb* libraries
}
}
function is_utf8_manual($str) {
// do stuff manually
}
if (function_exists('is_utf8_mb')) {
function is_utf8($str) {
is_utf8_mb($str)
}
} else {
function is_utf8($str) {
is_utf8_manual($str)
}
}
也就是說:執行環境中將存在一個is_utf8
變體,它僅依賴於它是否可以在該環境中工作。 每個變體都在一個最小大小的代碼塊中,以確定是否應該加載該變量並執行其功能。 主要原因是我認為編寫函數所需的空間量越小,讀者就越容易理解函數的行為。 你的眼睛必須減少旅行,你必須少滾動,一般來說,首次理解一個功能所涉及的瑣碎挫折通常較少。 第二個原因是它提供了一種更好的代碼測試方法 - 當您可以同時訪問所有這些代碼時,您可以更輕松地自動檢查is_utf8
變體例程產生相同結果的檢查。
這里有兩個方面:性能(不支付你不需要的東西)和可讀性。
正如許多明智的海報所說:在被證明是一個問題之前,不要擔心性能問題。
但是關於可讀性,在我看來,一個功能應該盡可能少地顯示責任層。 完全一件事的功能最容易理解。
你的問題實際上是關於'我應該如何混合兩個責任':
這就是為什么我真的會創建兩個'層':一個層調度到適當的函數,另一個層包含'代碼塊',包含在一個具有正確名稱的函數中。
然后你仍然可以選擇是否明確地進行調度,或者使用PHP的可能性來實時聲明函數。
// functionality: defines how to detect utf8 encoding
//
function is_utf8_mb( $arg ) {
... // using the mb library
}
function is_utf8_bare( $arg ) {
... // hand coded
}
// dispatching layer: decide what library to use
//
// option 1: define on-the-fly
function define_utf8_function() {
if( function_exists('mb_detect_encoding') ) {
function is_utf8( $arg ) { return is_utf8_mb( $arg ); }
} else {
function is_utf8( $arg ) { return is_utf8_bare( $arg ); }
}
}
// option 2: check the dispatching on each function call
function is_utf8_runtimedispatch( $arg ) {
if( function_exists('mb_detect_encoding') )
return is_utf8_mb( $arg );
else
return is_utf8_bar( $arg );
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.