函数处理函数

目录

添加注释

用户贡献注释 5 个注释

9
michael dot bommarito at gmail dot com
19 年前
我使用这些函数开发了一个易于使用的技巧来模拟重载函数。这对于构造函数和/或 C++ 风格的模板特别有用。

这是一个简单的示例,可以帮助你入门。这适用于大多数情况,如果你需要更智能的解析,使用正则表达式或更合适的分类方案来实现并不难。

注意:在 case 字符串中,变量类型之间没有空格。

class Matrix {

...

function Matrix() {
$args = func_get_args();
$argmatch = implode(",", array_map('gettype', $args));

switch( $argmatch ) {
case 'integer,integer'
// 初始化 m x n 矩阵
break;

case 'integer,integer,integer'
// 初始化 m x n 矩阵,并用常量 c 初始化
break;

case 'integer,integer,float'
// 初始化 m x n 矩阵,并用常量 c 初始化
break;

case 'array'
// 从数组初始化(二维...)
break;

case 'array,integer'
// 从数组初始化(一维,包含 m 行)
break;

default
// (void) 重载?
// 错误处理?
break;
}
}

...

}
-2
php dot spamguard at pulseforce dot com
15 年前
PHP 在允许你通过使用 func_* 函数向函数发送可变长度的参数列表方面非常出色。但是,不幸的是(这在 PHP 的 bug 报告/功能请求中被反复提及),它不支持按引用传递参数,这将极大地简化通过简单地执行 somefunction($a, $b, $c) 并处理它们来一次处理多个变量的过程,而无需进行任何额外的赋值。

但是,我发现了一种利用 PHP 的几个功能的方法,并创建了一个非常好的示例,展示了如何一次性处理多个变量!

用法如下(使用我的示例函数/类):
"list($a, $b, $c, $d, $e) = TextEscape::escape_multi($a, $b, $c, $d, $e);"

如果 PHP 实际上能够在使用可变长度参数列表时按引用传递变量,那么这可以简化为
"TextEscape::escape_multi($a, $b, $c, $d, $e);"

它非常接近,在简洁性和速度方面都非常接近。请务必始终在该语句的两侧使用相同数量和顺序的参数。

使用静态类只是为了使代码更简洁、更易于查看。这可以应用于任何函数!

现在,让我们来看代码,尽情享受这种非凡的技巧,并享受在一个语句中同时修改多个变量的乐趣! ;-)

<?php

class TextEscape
{
public static function
escape_string($sString)
{
/* 可以是任何东西,本示例中使用 htmlspecialchars() */
return htmlspecialchars($sString);
}

public static function
escape_multi()
{
/* 获取传递给函数的所有变量 */
$aVariables = func_get_args();

/* 遍历数组,对每个变量进行转义 */
foreach ($aVariables as $iKey => $sValue)
{
$aVariables[$iKey] = TextEscape::escape_string($sValue);
}

/* 返回转义后的值 */
return $aVariables;
}
}

// 创建测试变量
$a = "A<bar";
$b = "B>bar";
$c = "C<bar";
$d = "D>bar";
$e = "E<bar";

// 变量之前:
// 数组
// (
// [0] => A<bar
// [1] => B>bar
// [2] => C<bar
// [3] => D>bar
// [4] => E<bar
// )
print_r(array($a, $b, $c, $d, $e));

// 一次处理所有变量,
// 我们利用了 list() 和
// 可变长度参数列表的工作方式
// 使使用变得如此顺畅! ;-)
list($a, $b, $c, $d, $e) = TextEscape::escape_multi($a, $b, $c, $d, $e);

// 变量之后:
// 数组
// (
// [0] => A&lt;bar
// [1] => B&gt;bar
// [2] => C&lt;bar
// [3] => D&gt;bar
// [4] => E&lt;bar
// )
print_r(array($a, $b, $c, $d, $e));

?>

这是代码的简洁版本,它准确地说明了正在发生的事情。

我还制作了一个速度狂热版本的函数,但不想将其作为主要示例发布,因为它更难阅读。

但它更快,快得多!它在可以的地方按引用传递,并以更高效的方式循环。

只需用以下函数替换上面的函数,结果相同,但速度更快。

<?php

class TextEscape
{
public static function
escape_string(&$sString) // 更改:我们现在通过引用传递给实际的文本处理函数
{
/* 可以是任何东西,本例中使用 htmlspecialchars() */
$sString = htmlspecialchars($sString);
}

public static function
escape_multi()
{
/* 获取传递给函数的所有变量 */
$aVariables = func_get_args();

/* 循环遍历数组,转义每个变量 */
for ($i=(count($aVariables)-1); $i>=0; $i--) // 更改:使用更有效的 for 循环代替 foreach;对于想知道计数器声明的任何人,这是一个常见的优化技巧,它使数组的大小只需要检查一次,通过将计数器初始化为最后一个元素的索引(即数组大小减 1),然后向下迭代,直到我们达到 0(第一个元素)
{
TextEscape::escape_string($aVariables[$i]); // 更改:这已更改为通过引用修改变量
}

/* 返回转义后的值 */
return $aVariables;
}
}

?>

享受!
-2
Michael T. McGrew
19 年前
使用函数的一种有趣方式是将除 PHP 之外的其他内容放入其中,例如 HTML CSS。如果你将在多个页面中使用一种格式,这将非常有用。是的,也可以使用 include 函数,但通过在函数中定义它们,可以使它们在某种程度上更便携,并且可以避免创建许多包含文件。当要包含大量 PHP、HTML 和/或 CSS 代码并且将在多个页面中使用它们时,可以使用 include()。然后,当要包含较小部分代码并且只希望将其放在几个页面中时,可以在函数中使用 PHP、HTML 和/或 CSS 代码。

我在 PHP 编码的早期一直在使用 include() 来包含 HTML 和 CSS 代码,但现在我将更多地使用函数来完成这些操作。

<?php function a() { ?>
<style type="text/css">
table {
border: 1px dashed black;
background: #95EAFE;
text-align:left;
width:610px;
}
.linkbar {
font-family:sans-serif;
line-height:40px;
top:1px;
text-align:center;
width:200px;
height:10px;
}
</style>
<?php } ?>

现在执行
<?php a(); ?>
将返回所有 CSS 代码,就像你在实际页面中编写它或使用 include() 一样。在函数中包含 HTML 代码也是如此。可能性是无限的...
-2
php-note-2003-june-18 at ryandesign dot com
21 年前
Xavier 的例子比较复杂,他的任务可以通过使用类来更简单地完成。定义一个基类来执行基本函数 open、dump 和 close,并创建扩展类来覆盖任何行为。

class foo {
function open() {
// open() 的默认功能
}
function dump() {
// dump() 的默认功能
}
function close() {
// close() 的默认功能
}
}

class bar extends foo {
function open() {
// 覆盖 open() 的功能
}
// dump() 和 close() 仍然与类 foo 中的一样
}
-4
xmontero at dsitelecom dot com
21 年前
你可以在 PHP 中使用“function_exists”来执行某种函数重载。

假设你想要一个脚本调用作为 PHP 文件的插件,并且希望这些插件“覆盖”默认情况下使用的一些行为。

例如,你可能编写了一个“mySQL 表格查看器”,它显示一个表格,并“打开表格”、“转储表头”、“逐行转储”然后“关闭表格”。

假设你想要一个“股票”插件,它将负库存以红色打印,因此你想要覆盖“逐行转储”以执行此行为。相反,你不想在插件中重复所有“默认行为”。

然后你可以执行以下操作:

1) 定义一个默认插件(例如:“default.php”

2) 在 default.php 中编写所有用于打开、转储和关闭的函数,但添加一个后缀

open_table_default()
dump_header_default()
dump_row_default()
close_table_default()

3) 使用包装器调用你的函数:不要使用
open_table() 或 open_table_default(),而使用

plugincall("open_table");

4) 然后编写一个名为 plugincall 的函数,它使用 function_exists() 来查看是调用其中一个函数还是另一个函数

function plugincall($desired_function_name)
{

if( function_exists( $desired_function_name))
{
// 调用插件
// 注意名称前的 $
$desired_function_name()
}
else
{
$desired_function_name = $desired_function_name . "_default";
if( function_exists($desired_function_name))
{
// 调用默认值
// 注意名称前的 $
$desired_function_name()
}
else
{
// 插件和默认值均未定义
}
}

因此,现在,如果 require_once(plugin.php) 包含一个名为“open_table()”的函数,它将被使用。相反,将使用“open_table_default()”。

这不像函数重载,但对于编写可由其他程序员扩展的脚本非常有用:如果他们编写了一个函数,它将被使用,如果没有,则使用默认值。

再见!
Xavier Montero。
To Top