PHP的隐藏功能?[关闭]


174

我知道这听起来像是一个尖锐的问题,但让我解释一下我来自哪里。

大学毕业后,我在一家PHP商店找到了一份工作。我在那里工作了一年半,以为我已经学到了学习编程的全部知识。

然后,我在一家规模相当大的公司担任单人内部开发商店的工作,所有工作都在C#中进行。在担任这个职位时,我开始阅读大量的博客和书籍,并很快意识到我以为自己了解所有知识是多么错误。我了解了单元测试,依赖项注入和装饰器模式,松散耦合的设计原理,关于继承的讨论等等,而且我一再地学习这些知识。不用说,我的编程风格在去年完全改变了。

现在,我发现自己接了一个php项目,为朋友的启动做一些编码,与C#编程相比,我感到完全受了限制。确实让我感到困扰的是,必须通过附加'$ this->'来引用类范围内的所有变量。令我烦恼的是,我尝试过的所有IDE都没有很好的智能感知能力,而且我的SimpleTest单元测试方法必须以单词“ test”开头。动态类型使我无法隐式指定方法期望的参数类型,而必须编写switch语句来执行方法重载,这使我感到疯狂。我不能忍受不能有嵌套的名称空间,而必须使用::运算符来调用基类的构造函数。

现在,我无意开始进行PHP与C#的辩论,而是要确定我确信有些PHP功能我不知道或无法正确使用。我陷入C#宇宙中,无法在玻璃碗外面看。

所以我问,您最喜欢PHP的哪些功能?在.Net语言中,您可以做哪些事情,这些事情您做不到或很难做?


OO范式破裂?对我来说,这是您发现的最糟糕的“隐藏”功能。
knoopx

这些线程有点有趣...因为对于我来说,与团队一起工作的“隐藏功能”是一个表示“ bug”的代码短语。而且您知道吗...有时候发现隐藏的功能并不一定是一件好事...
Ganesh Shankar,2010年

@Ganesh 一个人的错误是另一个人的隐藏功能 ...
Xeoncross

Answers:


328

文件资料。该文档获得我的投票。我还没有遇到关于编程语言的更详尽的在线文档-我必须从各种网站和手册页中整理所有其他内容。


60
我同意。能够大多数时间输入www.php.net/function_name并获得参考。
Allain Lalonde

1
这是PHP的一个很棒的功能,但是我不会真正将其称为隐藏的。。。
John Bubriski

27
我也同意。手册最重要的是用户评论。我很少看到其他文档有这些内容。它们可以包含真正的宝石。唯一的缺点是恕我直言,他们修剪得太早了。
Sander Marechal,2009年

3
@Phoexo“一点点可读性差” 我从未理解也永远不会理解MSDN,而PHP文档却简单明了。
lauriys 2010年

3
不同意。该文档“好”的唯一原因是由于一些用户注释堵塞了官方说明中的所有漏洞。
罗布·霍华德,

179

数组。从这个问题的答案来看,我认为人们不会完全理解PHP中数组的简单性和实用性。PHP数组同时充当列表,映射,堆栈和通用数据结构。数组是在语言核心中实现的,并在各处使用,这会导致良好的CPU缓存局部性。Perl和Python都为列表和地图使用了单独的语言构造,从而导致更多的复制和可能引起混乱的转换。


11
PHP数组元素是有序的。
user8134

117
我最初从PHP迁移到C#几乎使我丧命。在C#中,数组只是具有静态大小和数字索引的简单结构。在PHP中,数组是宇宙的胶带!
Dinah

4
我也同意。使用Java进行Uni作业时,我惊讶于它们的刚性,根本没有灵活性。确实让我很欣赏PHP数组多么出色。
基督教徒

11
我确定php数组很棒,但40票的评论会敲响C#数组?如果C#数组不符合需要,则有很多选择。ArrayList和泛型集合都非常强大。有许多类型的集合可以满足特定需求。php在这方面的唯一实际优势是,它不提供程序员必须决定的任何选项。您要么使用数组,要么没有可索引的变量。
G-Wiz 2010年

24
另一方面,数组的语法完全糟透了。在许多脚本语言中,您可以创建一个简单的2D数组,如下所示:[[1, 2], [3, 4]],将其与PHP版本进行比较:array(array(1, 2), array(3, 4))
Rene Saarsoo,2010年

167

据我所知,流处理程序使您可以使用大多数其他语言很难做到的逻辑来扩展“文件系统”。

例如,使用MS-Excel Stream处理程序,您可以通过以下方式创建MS Excel文件:

$fp = fopen("xlsfile://tmp/test.xls", "wb");
if (!is_resource($fp)) { 
    die("Cannot open excel file");
}

$data= array(
    array("Name" => "Bob Loblaw", "Age" => 50),  
    array("Name" => "Popo Jijo", "Age" => 75),  
    array("Name" => "Tiny Tim", "Age" => 90)
); 

fwrite($fp, serialize($data));
fclose($fp);

我相信KIO框架也可以使您做到这一点,但这仅适用于基于KDE的桌面应用程序。
MiffTheFox

21
恕我直言,具有适当的面向对象方法比使用流处理程序的混乱要明智得多。是的,它很可爱,能够读取/写入Excel文件,但是它必须像这样工作吗?
Anti Veeranna

3
也许是这样,但是这种方法将复杂性封装在大多数PHP开发人员所共有的接口中……而无需他们学习可能超出他们范围的面向对象的概念。
阿兰·拉隆德

13
如果您正在使用Amazon S3,请查看Zend_Amazon_S3,它为诸如s3:// {bucket-name} / path之类的URL提供了流接口。
davidtbernal

通过读取PHP文件,进行一些字符串替换并将其通过eval()传递,我已经使用它为视图层创建了一个简单的DSL。例如,我做到了这样,只要选择并执行@-> someVar,就可以使用短标签,这样我就可以访问视图级数据。
Jasper Bekkers,2009年

131

魔术方法是彻头彻尾的方法,只要您调用不存在的方法,分配或读取不存在的属性等即可调用。

interface AllMagicMethods {
    // accessing undefined or invisible (e.g. private) properties
    public function __get($fieldName);
    public function __set($fieldName, $value);
    public function __isset($fieldName);
    public function __unset($fieldName);

    // calling undefined or invisible (e.g. private) methods
    public function __call($funcName, $args);
    public static function __callStatic($funcName, $args); // as of PHP 5.3

    // on serialize() / unserialize()
    public function __sleep();
    public function __wakeup();

    // conversion to string (e.g. with (string) $obj, echo $obj, strlen($obj), ...)
    public function __toString();

    // calling the object like a function (e.g. $obj($arg, $arg2))
    public function __invoke($arguments, $...);

    // called on var_export()
    public static function __set_state($array);
}

这里的C ++开发人员可能会注意到,PHP允许重载某些运算符,例如()(string)。实际上,PHP甚至允许重载更多,例如[]运算符(ArrayAccess),foreach语言构造(IteratorIteratorAggregate)和count函数(Countable)。


4
作为可用魔术方法实现的有用示例,请转到phpcodetips.blogspot.com/2008/07/domain-model-validation.html
grom

6
不同意。这比Smalltalk,Ruby和Python中的类似功能弱得多(并且大概是从其中之一复制而来)
finnw

34
PHP对该功能的实现要弱于其他语言,这一事实并没有使它在PHP中的作用减弱。
阿兰·拉隆德

2
__call()在具有map domain.com/controller/method/的框架中很棒
alex

7
魔术方法也慢得要命。小心使用它们。
亚历克斯·温斯坦

95

标准类是一个整洁的容器。我最近才知道的。

而不是使用数组来保存服务器属性

$person = array();
$person['name'] = 'bob';
$person['age'] = 5;

您可以使用标准班级

$person = new stdClass();
$person->name = 'bob';
$person->age = 5;

当访问字符串中的这些变量时,这特别有用

$string = $person['name'] . ' is ' . $person['age'] . ' years old.';
// vs
$string = "$person->name is $person->age years old.";

43
“ {$ person ['name']}年满{$ person ['age']}岁”作品。
Kornel

27
“ person [name]是$ person [age]岁”也可以使用...没有引号,没有大括号:)
majelbstoat

16
$ string = sprintf(“%s是%d岁。”,$ person ['name'],$ person ['age']);
2009年

60
当我们讨论主题时:(object)array(“ name” =>'bob','age'=> 5)
Annika Backstrom,2009年

30
@majelbstoat:删除引号会使脚本变慢,因为PHP解释器将查看是否已使用define(...)设置了“名称”和“年龄”。考虑到有可能完全翻转在每种情况下都可以访问的键,这也是一个不好的做法:define('age','name'); define('name','age');
brianreavis

90

包含文件可以具有可以分配给变量的返回值

// config.php
return array(
    'db' => array(
        'host' => 'example.org',
        'user' => 'usr',
        // ...
    ),
    // ...
);

// index.php
$config = include 'config.php';
echo $config['db']['host']; // example.org

@Peter 对db-> localhost异常错误处理非常有用。
Talvi Watia 2010年

设置快速且肮脏的配置文件非常方便。
Frank Farmer 2010年

为什么返回这个数组?如果包含的文件包含数组,则可以立即在include中使用。
fabrik

5
@fabrik,因为它将是全局变量,并且在整个主要范围内都可用。太不愉快了,这样更好。
Mikulas Dite 2010年

我在Yii框架中的一个项目上工作,那个项目有配置文件,其中数组是这样返回的,现在我明白了为什么文件是这样的。
oditiwebs.com 2010年

83

您可以利用以下事实,即or运算符的优先级低于=这样做的优先级:

$page = (int) @$_GET['page'] 
  or $page = 1;

如果第一个赋值的值为true,则第二个赋值将被忽略。另一个例子:

$record = get_record($id) 
  or throw new Exception("...");

7
我认为我不太相信。即使它似乎不容易出错,也有悖常理,并且它本身可能会导致错误。
thomasrutter

14
@Pies:以下是一种方法,说实话,代码很混乱:$ page = isset($ _ GET ['page'])?(int)$ _ GET ['page']:1;//这样的好处是不需要错误抑制。
DisgruntledGoat

3
再三考虑,因为您正在寻找一个整数,所以可以改用:$ page = is_int($ _ GET ['page'])?$ _GET ['page']:1;
DisgruntledGoat

4
值得注意的是,or如果之前的代码or产生数值,则后面的代码将执行0。因此,从语义上讲,类似这样的可能性较小$_GET['page'],但显然可能会出现这种情况,因此提请注意。
眼睑失明

3
还值得注意的是,该or运算符是该运算符的较低版本||。另外,+ 1是因为它具有很高的表现力,而我经常忘记这样做的可能性。应该更频繁地使用它,并且它的作用是绝对清楚的。我不知道“真正的男性”如何编码,因此我无法对此发表评论。
眼睑滑落

80

__autoload()(class-)文件的辅助set_include_path()

在PHP5中,现在在进行体面的OOP时不必指定很长的“ include_once”语句列表。

只需定义一小类目录,即可在其中构建类库文件,并设置自动包含路径:

set_include_path(get_include_path() . PATH_SEPARATOR . '../libs/');`

现在,__autoload()例程:

function __autoload($classname) {
    // every class is stored in a file "libs/classname.class.php"

    // note: temporary alter error_reporting to prevent WARNINGS
    // Do not suppress errors with a @ - syntax errors will fail silently!

    include_once($classname . '.class.php');
}

现在,PHP将自动按需包含所需的文件,从而节省了解析时间和内存。


是spl_autoload_register()更好用的吗?
alex

19
当然!__autoload()是PHP4,但是spl_autoload_register()是自动加载方法的非破坏性“菊花链”。
威廉

3
一个方便的功能,但一个警告是,当您找到给定类的实例时,使查找类文件的位置更加困难。在顶部明确定义包含,可以为您提供所涉及类及其确切位置的有限列表。
Cory House

这是一个很好的功能,但是只是为了避免不进行代码预编译的情况,因此它不知道类的位置。这样做的一个很大的缺点是,即使它们位于不同的命名空间中,您也不能拥有两个具有相同名称的类。
Kibbee

3
实施自动加载时,请查看PHP标准工作组(具有ZF,Symfony,Doctrine,CakePHP,Solar等的开发人员)的PSR-0提案:groups.google.com/group/php-standards/web / psr-0-final-proposal
Philippe Gerber

76

易用性。最大的功能是让新开发人员坐下来编写“工作”脚本并理解代码有多么容易。

最糟糕的功能是让新开发人员坐下来编写“工作”脚本并认为他们理解代码是多么容易。

围绕PHP 的社区开放性以及作为开放源代码提供的大量PHP项目对于那些进入开发世界的人并没有像对您这样的人来说可能会令人生畏,这可以成为进入更成熟语言的垫脚石。

我不会像以前讨论过很多技术性问题,但是如果您将PHP视为社区而不是Web语言,那是一个在您开始开发时就明确地拥抱了您的社区,那么好处是不言而喻的。


3
绝对是一个很好的评论。Python是我的第一语言,它很棒,但是缺乏我认为能够理解的项目确实造成了障碍。使用PHP,我可以在文档中查找几乎所有内容并弄清楚...网络上可用的资源非常棒。
dscher 2010年

76

毫无疑问,可变变量和函数

$foo = 'bar';
$bar = 'foobar';
echo $$foo;    //This outputs foobar

function bar() {
    echo 'Hello world!';
}

function foobar() {
    echo 'What a wonderful world!';
}
$foo();    //This outputs Hello world!
$$foo();    //This outputs What a wonderful world!

相同的概念适用于对象参数($ some_object-> $ some_variable);

非常非常棒。Make的使用循环和模式进行编码非常容易,并且比eval更快,更受控制(感谢@Ross和@Joshi Spawnbrood!.t)


111
可变变量实际上使代码的可读性降低,更容易出错。
Elzo Valugi 09年

8
人们真的使用这个吗?伙计,我不愿阅读这些资料。
加里·威洛比2009年

27
变量变量是PHP提供的最糟糕的功能之一。
davidtbernal

10
9在10倍的变量变量中,最好用数组替换,这样您就可以将所有数据都放在一个位置,可以遍历数据等等。仅在某些非常特殊的情况下它们才有用。
Jasper Bekkers,2009年

7
请不要让新手使用该“功能”。
whiskeysierra

68

您可以使用功能与参数的不确定数量的使用func_get_args()

<?php

function test() {

    $args = func_get_args();
    echo $args[2]; // will print 'd'
    echo $args[1]; // will print 3
}

test(1,3,'d',4);

?>

1
即将发布。有点像JS函数中的arguments属性。
alex

67

我喜欢远程文件。对于Web开发,这种功能格外有用。

需要使用网页的内容吗?一个简单的

$fp = fopen('http://example.com');

就像其他任何普通文件一样,您已经准备好使用文件句柄。

还是直接将远程文件或网页读入字符串中呢?

$str = file_get_contents('http://example.com/file');

这种特定方法的有用性很难高估。

是否要分析远程图像?如何通过FTP进行操作?

$imageInfo = getimagesize('ftp://user:password@ftp.example.com/image/name.jpg');

几乎所有与文件一起使用的PHP函数都可以与远程文件一起使用。你甚至可以include()require()代码文件远程这种方式。


2
这是这么好看!要在例如Java中做到这一点,您需要包含一个gazillion jar文件,而不是编写大量样板代码。
金布尔

16
“您甚至可以通过这种方式远程包含()或require()代码文件。” 当然,在不受控制的服务器上包含()包含文件是一个可怕的想法。
Frank Farmer 2010年

4
@Frank -是的,好了,人们会认为您会包括你的服务器代码做了控制。
zombat

1
实际上,远程文件包含是一个常见的PHP安全问题:en.wikipedia.org/wiki/Remote_File_Inclusion#PHP
Frank Farmer 2010年

63

strtr()

它的速度非常快,以至您会感到惊讶。在内部,它可能使用一些疯狂的b树类型结构来按其公共前缀排列您的匹配项。我将它与200多个查找和替换字符串一起使用,并且它在不到100ms的时间内仍通过了1MB。对于所有很小的字符串,即使考虑到字符集,strtr()在做完全相同的事情时也比strtolower()更快。您可能使用连续的strtr调用编写了一个完整的解析器,它比通常的正则表达式匹配要快,找出了令牌类型,输出了这个或那个,接下来是正则表达式。

我正在编写一个文本标准化器,用于将文本拆分为单词,小写字母,删除标点符号等,strtr是我的瑞士军刀,它使正则表达式甚至str_replace()脱颖而出。


1
它可能会更快,因为它可以替换单个字符。
staticsan

10
strtr()不仅执行单字符替换。它可以用其他任意长度的子字符串替换任意长度的子字符串,而且看起来仍然非常快。
thomasrutter

1
您提到在某些情况下它比strtolower更快,您能证明吗?我做了一个小的基准测试,发现它是错误的。
Pixel Developer

1
我发现在说80个字符的小字符串上它比strtolower慢,而在说1MB的大字符串上它更快。每次调用可能都有一些固定成本类型的开销。我只是在使用strtr($ this-> string,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'); 我正在处理的字符串是一些典型的英语文本(“棕色狐狸”之类的东西)。
thomasrutter

我刚刚阅读了这篇文章,然后进行了一些Google搜索,发现: simplemachines.org/community/index.php ? topic=175031.0知道哪个是正确的吗?
Flipper

61

PHP的extract()一个鲜为人知的功能是,该功能将关联数组拆包到本地名称空间中。对于自动全局堕胎,这可能存在,但是对于模板化非常有用:

function render_template($template_name, $context, $as_string=false)
{
    extract($context);
    if ($as_string)
        ob_start();
    include TEMPLATE_DIR . '/' . $template_name;
    if ($as_string)
        return ob_get_clean();
}

现在,您可以使用render_template('index.html', array('foo' => 'bar'))并且仅$foo将值"bar"显示在模板中。


15
我会为您生气而以任何方式建议extract()是一个好功能。但是我想使用它非常方便。我想这是我第一次看到它是个好主意!
thomasrutter

5
extract()使滚动自己非常轻量的模板系统变得非常简单。+1
黛娜(Dinah)2009年

14
它的反函数compact()也很好:$ a = 1; $ b = 2; compact('a','b'); // == array('a'=> $ a,'b'=> $ b)
Annika Backstrom,2009年

2
是的,那可能是extract()的唯一真正好的用法。
staticsan

4
在这种情况下,我建议不要使用常用词作为函数参数名称,因为您从extract()提取的$ context可能包含'as_string'或'template_name'索引处的值。使用EXTR_SKIP是可以接受的,但只能将问题转移到其他地方(即,如果模板期望$ as_string,它将获得不正确的值。)
MichałTatarynowicz,2009年

52

Range()本身并不是隐藏的,但是我仍然看到很多人在迭代:

for ($i=0; $i < $x; $i++) { 
    // code...
}

什么时候可以使用:

foreach (range(0, 12) as $number) {
    // ...
}

您可以做一些简单的事情,例如

foreach (range(date("Y"), date("Y")+20) as $i)
{
print "\t<option value=\"{$i}\">{$i}</option>\n";
}

3
您可以执行foreach(将$ array作为$ key => $ value){}甚至更简单。
SilentGhost

15
这可能是一个微优化,但值得注意的是,与foreach相比,for和while速度更快,内存占用更少。
日,日本

3
您应该尝试使用Python。就像“ for i in range(12)”一样简单,或者您可以使用更高效的xrange。
Ponkadoodle

2
@SilentGhost:您仍然需要一个数组作为开始,但情况并非总是如此。@Newbie:请详细点吗?
亚历克

1
@flexxy,显然不是。考虑一下:phpbench.com向下滚动到Read Loop
好友

44

启用PHP的网站空间通常比(asp).net便宜。您可以将其称为功能;-)


3
如果您不必为每台Windows Server都付费,则设置多台服务器也便宜得多。
MiffTheFox

4
我唯一知道Windows在哪里具有成本效益的地方是一所大学,它在服务器软件上获得STEEEEP折扣,这比我的部门购买100个Windows副本便宜得多,而这比在linux上培训我们的管理员便宜(部分让我伤心,但他们的Windows设置干净而且设置正确)。
dcousineau

4
现在,但是您只需要进行一次转换,而您迟早要购买新许可证...
e-satis

42

static关键字是OOP的观点来看是有用的外部。您可以使用以下简单的方法快速轻松地实现“内存化”或函数缓存:

<?php
function foo($arg1)
{
    static $cache;

    if( !isset($cache[md5($arg1)]) )
    {
        // Do the work here
        $cache[md5($arg1)] = $results;
    }

    return $cache[md5($arg1)];
}
?>

static关键字创建仍然存在仅功能过去执行的范围内的变量。这项技术非常适合击中数据库的功能,get_all_books_by_id(...)或者get_all_categories(...)您在页面加载期间多次调用这些功能。

警告:请确保您找到为哈希创建密钥的最佳方法,在几乎每种情况下,md5(...)上述都不是一个好的决定(速度和输出长度问题),我将其用于说明目的。sprintf('%u', crc32(...))spl_object_hash(...)根据情况可能更好。


7
只是从C / C ++复制的功能
GetFree

2
@GetFree我想没有人会否认,几乎所有PHP已经从C,C ++,Perl等复制
弗兰克农民

1
复制是可以做的最好的事情。
NikiC

1
错误的PHP。它总是在复制他人的功能。它应该从头开始编写所有内容!(如果有可能被认真对待,我在开玩笑)
HalilÖzgür

42

PHP的一个不错的功能是CLI。在文档中并不是那么“提倡”,但是如果您需要例行脚本/控制台应用程序,那么使用cron + php cli确实可以快速开发!


我真的应该对此进行研究,我有几个cron作业可以通过以下方式获取PHP脚本wget http://example.com...
DisgruntledGoat 2010年

CLI也是一种出色的现场调试方式,因为警告/错误将显示出来,而您无需更改错误报告首选项。
Glacials 2011年

40

然后是“和打印”技巧

<?php $flag and print "Blah" ?>

如果$ flag为true,将回显Blah。不适用于ECHO。

这在模板和替换中非常方便。:那不是很容易阅读。


24
我自己发现,三元运算符比利用逻辑和的评估短路更为明显。
森特·马蒂

26
实际上,这与<?php if($ flag)打印“ Blah”的字符数相同
太多的PHP

3
括号不像“和”那么容易键入,尤其是在我的流血法语键盘上;-)
e-satis

7
@all评论-这与您能得到多短无关!它与模板人员(有时甚至不是程序员)的可读性和易用性有关。
Tor Valamo

6
我要评论一下if()语句更容易理解。与本质上利用PHP中的“ and”运算符的副作用相比,对我而言,这样做无疑要容易得多,因为在PHP中“&”运算符很容易犯错误(或者稍后阅读代码时看起来像是一个错误)。例如,如前所述,这与您想要的'echo'方式不同。使用if()不会遇到这样的麻烦。
thomasrutter

37

您可以在变量名称中使用减号,如下所示:

class style
{
  ....
  function set_bg_colour($c)
  {
    $this->{'background-color'} = $c;
  }
}

为什么要使用它?不知道:也许是CSS模型?或者您需要输出一些奇怪的JSON。这是一个奇怪的功能:)


2
可以使用方法名称吗?对于使用路由器并且我想要domain.com/something-with-minuses/view/的框架可能有用
alex

6
大括号可让您访问具有破折号,点和其他非字母数字实体的对象属性。使用它的一个原因是在处理xml时,其中的实体名称可以像在NITF / NewsML <body.content>中那样点缀起来。如果使用SimpleXML,您将像这样访问它$item->DataContent->body->{'body.content'}
杰西·高知

2
以这种方式使用时,PHP变量可以包含任何字符,甚至空格和换行符。
新手

当在SimpleXML中使用时,这将非常有用。感谢分享。
KyleFarris 2011年

34

HEREDOC语法是我最喜欢的隐藏功能。始终很难找到,因为您无法使用Google << <<,但是它使您不必转义大块HTML,仍然允许您将变量放入流中。

echo <<<EOM
  <div id="someblock">
    <img src="{$file}" />
  </div>
EOM;

2
HEREDOC是我最喜欢的构建和使用SQL语句的方法。
bdl 2010年

11
注意:关闭EOM;不能缩进。
micahwittman 2010年

很好,但是如果使用模板则毫无意义。另外,它会妨碍正确的缩进。
Manos Dilaverakis 2010年

7
亲爱的上帝,那是我见过的最丑的代码。如果您使用的是HEREDOC,那么您还没有将表示与逻辑分离。
Lotus Notes 2010年

@Byron:您不必使用它进行演示,它可以用于任何字符串。请参阅bdl的评论。
汤姆·帕索里克(TomPažourek),2010年

34

可能没有多少人知道可以将常量“变量”指定为函数参数的默认值:

function myFunc($param1, $param2 = MY_CONST)
{
//code...
}

字符串可以用来作为如果他们数组

$str = 'hell o World';
echo $str; //outputs: "hell o World"

$str[0] = 'H';
echo $str; //outputs: "Hell o World"

$str[4] = null;
echo $str; //outputs: "Hello World"

3
最后一个很漂亮。虽然我不知道什么时候会比其他删除字符的方法更好。不过+1
George Mauer 2009年

3
它可能比调用一个函数更有效。字符串通常连续存储在内存中,因此进入$ str [4]是微不足道的。将字符串存储为字符数组对于大多数源自C的语言都是通用的
。– sjobe

1
您不必使用定义的常量作为默认值。以下内容也完全有效:function foot($ param1,$ default = array('key'=>'value'),$ default_s ='String',$ default_i = 10,$ default_b = false)。但是,您不能将变量用作默认参数是正确的。
dcousineau

@dcousineau您的示例完全有效,因为array()不是函数,而是语言构造。不允许将函数调用作为参数的默认值。
Jamol

4
如果您有多字节字符串(外语等),请小心将字符串视为数组
philfreo 2011年

33

关于PHP代码,最有用的一点是,如果我不太了解某个函数,可以通过使用浏览器并键入以下命令来查找它:

http://php.net/function

上个月,我在某些代码中看到了“范围”功能。它是我从未使用过但真正有用的数百个功能之一:

http://php.net/range

该url是http://us2.php.net/manual/en/function.range.php的别名。将函数和关键字映射到url的简单想法很棒。

我希望其他语言,框架,数据库,操作系统具有查找文档的简单机制。


5
range()可能有用foreach( range(1, 10) as $i) { };
alex

如果您有FireFox;只需PHP function在地址栏中输入内容,它就会进行Google“我很幸运”搜索,您几乎总是会在正确的php文档页面中找到最终结果。
Kolky 2010年

30

快速块评论

/*
    die('You shall not pass!');
//*/


//*
    die('You shall not pass!');
//*/

这些注释使您可以切换是否用一个字符注释一个代码块。


14
这并不是真的专门针对PHP。此功能适用于支持// ...行注释和/* ... */块注释的任何语言。
乔丹·瑞安·摩尔

任何代码清理实用程序最终都讨厌您使用此代码...;)
Talvi Watia 2010年

3
/** /之前和/**/之后也用过。您可以通过在第一个中删除并添加空格来切换块。使用CSS(和其他不支持// ... 注释的语言)可以带来额外的好处。
kingjeffrey 2010年


@aleemb,请勿对此问题进行任何进一步的编辑。
Sam152'9

29

我的清单..他们中的大多数都比“最喜欢的功能”更受“隐藏功能”的影响(我希望!),并且并非所有功能都有用,但是..是的。

// swap values. any number of vars works, obviously  
list($a, $b) = array($b, $a);

// nested list() calls "fill" variables from multidim arrays:  
$arr = array(  
  array('aaaa', 'bbb'),  
  array('cc', 'd')  
);  
list(list($a, $b), list($c, $d)) = $arr;  
echo "$a $b $c $d"; // -> aaaa bbb cc d  

// list() values to arrays  
while (list($arr1[], $arr2[], $arr3[]) = mysql_fetch_row($res)) { .. }  
// or get columns from a matrix  
foreach($data as $row) list($col_1[], $col_2[], $col_3[]) = $row;

// abusing the ternary operator to set other variables as a side effect:  
$foo = $condition ? 'Yes' . (($bar = 'right') && false) : 'No' . (($bar = 'left') && false);  
// boolean False cast to string for concatenation becomes an empty string ''.  
// you can also use list() but that's so boring ;-)  
list($foo, $bar) = $condition ? array('Yes', 'right') : array('No', 'left');

您也可以嵌套三元运算符,有时会派上用场。

// the strings' "Complex syntax" allows for *weird* stuff.  
// given $i = 3, if $custom is true, set $foo to $P['size3'], else to $C['size3']:  
$foo = ${$custom?'P':'C'}['size'.$i];  
$foo = $custom?$P['size'.$i]:$C['size'.$i]; // does the same, but it's too long ;-)  
// similarly, splitting an array $all_rows into two arrays $data0 and $data1 based  
// on some field 'active' in the sub-arrays:  
foreach ($all_rows as $row) ${'data'.($row['active']?1:0)}[] = $row;

// slight adaption from another answer here, I had to try out what else you could  
// abuse as variable names.. turns out, way too much...  
$string = 'f.> <!-? o+';  
${$string} = 'asdfasf';  
echo ${$string}; // -> 'asdfasf'  
echo $GLOBALS['f.> <!-? o+']; // -> 'asdfasf'  
// (don't do this. srsly.)

${''} = 456;  
echo ${''}; // -> 456  
echo $GLOBALS['']; // -> 456  
// I have no idea.  

对,我现在停下来:-)


嗯,已经有一段时间了。

// just discovered you can comment the hell out of php:
$q/* snarf */=/* quux */$_GET/* foo */[/* bar */'q'/* bazz */]/* yadda */;

因此,刚发现可以使用大括号将任何字符串作为方法名称进行传递。不能将任何字符串定义为方法,但是可以使用__call()捕获它们,并根据需要进一步处理它们。嗯...

class foo {
  function __call($func, $args) {
    eval ($func);
  }
}

$x = new foo;
$x->{'foreach(range(1, 10) as $i) {echo $i."\n";}'}();

在Reddit评论中发现了这个小宝石:

$foo = 'abcde';
$strlen = 'strlen';
echo "$foo is {$strlen($foo)} characters long."; // "abcde is 5 characters long."

您不能像这样直接在{}内部调用函数,但是可以使用variable-holding-the-function-name并调用它们!(*和*您也可以在其上使用变量变量)


2
请不要滥用三元比较运算符;这导致代码混淆。
staticsan

哇。这样可以完全消除您的$ GLOBALS列表。不好的做法。说真的
Talvi Watia 2010年

是否有混淆不清的PHP竞赛?
Lotus Notes 2010年

好吧,交换技巧-令人印象深刻且有用,谢谢。
OZ_

1
${''} = 456;哈哈哈。
Skurmedel 2011年

26

数组操作。
大量用于处理和操作数组的工具。它可能不是PHP所独有的,但我从未使用过使它如此简单的语言。


像什么?在我看来,这些函数都笨拙地命名并定位在全局名称空间中。另外,我想不出另一种语言,除了$ arr [] = $ newvalue来添加值之外,没有什么比这更容易的了–太酷了
George Mauer

8
嗯,PHP数组是一种可以轻松用作堆栈,队列,双端队列,列表,哈希表等的数据结构。对于大多数常见需求而言,它确实非常灵活,无需使用array_ *函数即可。
卡米洛·迪亚斯·雷普卡

6
Python的数组(如列表和元组)比PHP的要好得多。
太多的PHP

26

我有点像您,我已经为PHP编码了8年以上。大约一年前,我不得不参加.NET / C#课程,我真的很喜欢C#语言(讨厌ASP.NET),但是这使我成为了一个更好的PHP开发人员。

PHP作为一种语言是相当差的,但是,我使用它非常快,并且LAMP堆栈很棒。最终产品远远超过零件的总和。

也就是说,在回答您的问题时:

http://uk.php.net/SPL

我爱SPL,一开始我就很喜欢C#中的collection类。现在我可以吃蛋糕了。

安德鲁


24

令我惊讶的是,还没有人提到它,但是我最喜欢的数组技巧之一是使用加号运算符。它有点像,array_merge()但是更简单。我发现这通常是我想要的。实际上,它接受RHS中的所有条目,并使它们出现在LHS的副本中,并在必要时进行覆盖(即,这是不可交换的)。对于从“默认”数组开始并一次添加所有实际值,同时为未提供的值保留默认值非常有用。

请求的代码示例:

// Set the normal defaults.
$control_defaults = array( 'type' => 'text', 'size' => 30 );

// ... many lines later ...

$control_5 = $control_defaults + array( 'name' => 'surname', 'size' => 40 );
// This is the same as:
// $control_5 = array( 'type' => 'text', 'name' => 'surname', 'size' => 40 );

$defaults应该是$control_defaults
diEcho

3
当您需要维护大量代码时,我认为它不如array_merge清晰。至少在使用array_merge函数时,很明显,您正在处理数组。
西尔万

而您正在做的事实... + array( ...还不足以指出这一点吗?:-)
staticsan

您需要哪个版本的PHP?
Lotus Notes 2010年

这是一个很大的功能,应注意,“ +”的“右侧”上的数组不会将阵列的现有键覆盖到“ +”的“左侧”上。
Wil Moore

21

这是一个,我喜欢如何未提供的函数参数上设置默认值更容易:

function MyMethod($VarICareAbout, $VarIDontCareAbout = 'yippie') { }

4
有趣的是,上周我在Google阅读器中看到了此“隐藏功能”。我不了解它的隐藏之处-它是基本语法。例如,尝试if($ var = true)。
罗斯,

8
比什么还容易?大多数语言都具有此功能。
ChristianDavén09年

10
比C#(我认为C ++和Java)更容易
George Mauer 2009年

8
C ++确实支持默认参数值。
sjobe

2
C#根本不支持默认值。您必须编写一个重载的函数,并始终声明很普通的值
DeveloperChris 2010年

21

快速和肮脏是默认设置。
该语言充满了有用的快捷方式,这使PHP成为上市时间短的(小型)项目的理想选择。并不是说干净的PHP代码是不可能的,而是需要一些额外的精力和经验。

但是我喜欢PHP,因为它使我无需输入论文即可表达自己的需求。

PHP:

if (preg_match("/cat/","one cat")) {
   // do something
}

JAVA:

import java.util.regex.*;
Pattern p = Pattern.compile("cat");
Matcher m = p.matcher("one cat")
if (m.find()) {
  // do something
}

是的,这包括不键入Int


4
您应该改用strpos:if(false!== strpos(“ one cat”,“ cat”)){
OIS,2009年

17
@OIS他的示例的目的是为了说明和比较快速正则表达式匹配的运行方式,而不是如何在“一只猫”中找到字符串“ cat”。
dcousineau

19
Java:if(Pattern.matches(“ cat”,“一只猫”)){//做某事}如果您不知道Java,请停止抱怨。
whiskeysierra

3
+1 Willi你怎么做preg_replace('/([[[[]!-\ s *)(\ S *?)(\ s *-[>]]?)/ se',“ \ $ this- >选择('\\ 1','\\ 2','\\ 3',\ $ data)“,$ text); 在Java中?这将在输入文本中找到注释,然后调用具有匹配元素的函数,在这种情况下,$ this-> choose(...)决定用什么替换匹配项并返回结果。
DeveloperChris 2010年

1
Regex是PHP的cr脚……我宁愿使用Perl或JavaScript样式的Regex,//该语言也已内置在内。
cdmckay 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.