PHP Conference Japan 2024

函数处理函数

目录

添加注释

用户贡献注释 5 条注释

9
michael dot bommarito at gmail dot com
19 年前
我已经开发了一个使用这些函数模拟重载函数的易于使用的技巧。它对于构造函数和/或 C++ 样式模板特别方便。

这是一个让你开始的小例子。这在大多数情况下都能解决问题,如果你需要更智能的解析,使用正则表达式或更合适的分类方案并不难实现。

注意:请注意字符串中变量类型之间缺少空格。

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 错误报告/功能请求中多次被提出),它不支持按引用传递参数,这将极大地简化同时处理多个变量的过程,只需执行: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 函数,但是通过在函数中定义它们可以使它们在某种程度上更易于移植,并避免您必须创建许多 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
22 年前
您可以使用“function_exists”在 PHP 中进行某种函数重载。

假设您希望一个脚本调用作为 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