[英]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.