每个优秀的PHP开发人员都应该能够回答的问题[关闭]


75

我正在研究每一个好的.Net开发人员都应该能够回答的问题,并且对该问题的内容和方法印象深刻,因此,本着同样的精神,我正在向PHP开发人员提出这个问题。

您认为一个好的PHP程序员应该回答什么问题

编辑:我将此问题标记为社区Wiki,因为它不是特定于用户的,它旨在为整个编程社区提供服务。

期待一些惊人的回应。

注意:也请按照评论中的建议回答问题,以便人们也可以学习有关该语言的新知识。


1
这里有类似的问题,关于“ PHP程序员要避免的常见错误”:stackoverflow.com/questions/1186957

Answers:


50

诚然,我从其他地方偷了这个问题(不记得我在哪里读了),但认为这很有趣:

问:什么T_PAAMAYIM_NEKUDOTAYIM
A:其范围解析运算符(双冒号)

经验丰富的PHP'er立刻知道它的含义。经验不足(而不是希伯来语)的开发人员可能想阅读此内容

但是现在有更严重的问题:


问:产生此警告的原因是:“警告:无法修改标题信息-标题已发送”,有什么好的方法来防止出现这种情况?
答: 原因:正文数据已发送,导致标头也发送了。
预防措施:输出任何正文数据之前,请务必先执行标头特定的代码。确保您没有意外发送空格或任何其他字符。


问:此查询出了什么问题"SELECT * FROM table WHERE id = $_POST[ 'id' ]"
答: 1 .易受SQL注入攻击。切勿在查询中直接使用用户输入。首先将其消毒。最好使用准备好的语句(PDO。2.不要选择所有列(*),而是指定每一个列。这主要是为了防止例如在将来某个时候添加BLOB列时查询占用内存。


问: if语句有什么问题if( !strpos( $haystack, $needle ) ...
A: strpos返回第一次找到$ needle的索引位置,可能是0。由于0也解决false了解决方案是使用严格的比较:if( false !== strpos( $haystack, $needle )...


问:编写此if语句的首选方式是什么,为什么?
if( 5 == $someVar )if( $someVar == 5 )
A:前者是因为这样可以防止在您忘记使用2个等号($someVar = 5)时意外地将$ 5分配给$ someVar ,并且会引起错误,而后者则不会。


问:给出以下代码:

function doSomething( &$arg )
{
    $return = $arg;
    $arg += 1;
    return $return;
}

$a = 3;
$b = doSomething( $a );

...什么是价值$a$b功能调用之后,为什么?
答: $a4$b3。前者是因为$ arg是通过引用传递的,后者是因为函数的返回值是参数初始值的副本(而不是对参数的初始值的引用)。


面向对象

问:是什么区别publicprotected并且private在类的定义?
答: public使类成员对“所有人”可用,protected使类成员仅对自身和派生类private可用,使类成员仅对类本身可用。


问:此代码有什么问题:

class SomeClass
{
    protected $_someMember;

    public function __construct()
    {
        $this->_someMember = 1;
    }

    public static function getSomethingStatic()
    {
        return $this->_someMember * 5; // here's the catch
    }
}

答:静态方法无权访问$ this,因为可以在不实例化类的情况下执行静态方法。


问:接口和抽象类之间有什么区别?
答:接口定义实现类is与调用该接口的对象之间的协定。抽象类为将扩展它的类预定义了某些行为。在某种程度上,这也可以视为合同,因为它可以保证存在某些方法。


问:主要定义getter和setters,直接映射到其内部成员而实际上没有执行行为的方法的类有什么问题?
答:这可能是代码的味道,因为该对象充当了高尚的数组,没有太多其他用途。


问:为什么PHP的使用接口实现次优?
答: PHP不允许您定义方法的预期返回类型,这实际上使接口变得毫无用处。:-P


28
strpos不抬头我就无法回答这个问题php.net/strpos。我觉得没有必要浪费脑筋来记住PHP的基本功能,即那些乱码为-1,哪些为假,哪些为空以及哪些完全不同。我发现其他问题没问题。
Pekka 2010年

19
Pekka:但是您应该知道字符串是零索引的,因此strpos必须能够为找到的前缀返回零。
Draemon

5
对不起,但是... -1。这些问题仅检查基础知识,例如访问修饰符或类(静态)和对象(动态)的方法/字段之间的差异。此外,这些问题并没有考验任何思维能力(对不起,我不懂英语单词来解释它)。我的意思是,你不检查编程是否能够创建非标准算法等
Crozin

36
尽一切应有的尊重,T_PAAMAYIM_NEKUDOTAYIM是对相关知识的毫无价值的考验。
桑普森

30
5 == $someVar一个是一个愚蠢的问题。不知道为什么这种编码风格固有地存在缺陷,为什么会得到如此多的赞誉。
DisgruntledGoat 2010年

24

绝对是安全性问题!

(这篇文章中的简单答案,当然,保护php Web应用程序的安全要复杂得多)

  • 如何处理SQL注入?

mysql_real_escape_string()从MySQL开始。然后尝试学习PDO,以利用准备好的语句和跨数据库供应商的可移植性。

  • 如何处理CSRF(跨站请求伪造)?

在每个重要请求上添加一个令牌以保护重要操作(用户在发送关键请求之前必须已经查看了表单)。

  • 如何处理反映和存储的XSS(跨站点脚本)?

htmlentities()适合作为一个开始。

  • XXX注入的变体:LDAP注入,XPath注入等...?

您需要知道XXX使用的“词汇表”,然后扣除您需要进行清理和/或“检查并拒绝”的内容。

  • 明智的功能清单是什么?

解释PHP代码(可能包含在远程文件中)或在系统上执行命令的函数。一个简短且不完整的列表可能是:exec(),passthru(),system(),popen(),eval(),preg_replace()...

  • 如何处理文件包含危险?
  • 什么是横向路径?
  • 文件上传有哪些风险?

打开文件或远程资源时,需要仔细检查使用的参数。

  • 如何执行您的PHP配置的配置(即,您知道php.ini的用途是什么)吗?

这将很长,因此我跳过了答案,请阅读PHP手册。

  • 关于过滤用户数据:清理检查并拒绝之间有什么区别?

第一个将条目转换为较少敌意的内容。第二个检查输入是否正确,如果不正确则拒绝输入。


尽管我同意您应该酌情知道如何处理SQL注入,但是为什么您说这对所有优秀的PHP程序员都是必要的呢?我不会说我对PHP很好,但是确实编写了一个与SQL无关的Web应用程序,并且尝试进行SQL注入会惨遭失败。我知道还有其他人在做类似的工作。(仅供参考,该应用程序处理并绘制了无法很好地适合SQL数据库的科学数据。)
GreenMatt 2010年

好吧,这个问题有点“含糊”,并且由于大多数PHP(Web)应用程序都需要数据库,因此我包含了SQL内容。
卡托奇

4
+1。尽管大多数答案是:使用适当的框架或库...
back2dos

14

“你为什么不使用其他东西?”

抱歉,有人不得不说:)


24
实际上,我认为这是一个好问题。开发人员应该能够解释为什么他们选择一种语言/框架/技术而不是另一种语言,并且答案不应该是“因为我从未尝试过其他方法”。与替代方法相比,PHP确实有优点和缺点,并且与流行的(或也许是精英主义者)信念相反,使用它有充分的理由。
日,日本

1
这是一个很好的问题……虽然我不喜欢PHP,但我发现在某些情况下有很多充分的理由使用它……
back2dos

2
在面试PHP / LAMP职位时,肯定会问过我。我同意这是一个有效的问题。
markb 2010年

12

是php跨浏览器吗?

(我知道,这会让很多人大笑,但这是php论坛上问得更多的问题!)


9
+1。我不知道该笑还是哭...:D
back2dos

通常我认为“这就是我们选择最流行的Web编程语言所获得的”
Strae 2010年

11

我认为一个好问题是:HTTP如何工作?与工作GET以及POST其他HTTP通信中的数据是在PHP开发所固有的。理解HTTP在更广泛的上下文中如何工作以及PHP如何实现这一点还有很长的路要走。


9

==和===有什么区别?为什么要完全使用==?


1
因为如果您已经知道要使用的变量的类型,则在比较中无需进行类型检查的开销。如果您不知道变量的类型,那么与使用错误的比较器相比,您会遇到更大的问题。
Mike

1
'==='比'=='的执行速度更快
Ehtesham

1
“ ==”是相等的,但不一定是同一类型,“ ===”表示它们是相等的并且是同一类型。例如,这段代码:<?php if(true ==“ true”){echo'first'; } if(true ===“ true”){echo'second'; }?>将仅首先输出,因为“ true”是字符串,并且是布尔值。
zuzuleinen

9

解释为什么显示以下代码2.5而不是3

$a = 012;
echo $a / 4;

回答:当数字前面有一个0在PHP,号数被作为一个八进制数(基数-8)。因此,八进制数012等于十进制数10


8

尚无人提及,但这是每个PHP开发人员都应该详细谈论的事情:为什么register_globals不好?


实际上,我希望它不需要冗长的发言……对于这个可怕的想法,一两个句子就足够了!
日,日本

2
register_globals与使用变量而不先定义变量的开发人员一样糟糕。
Matteo Riva

7

当使用php开发网站并且完全废话时,它是:

a)PHP的错误

b)程序员故障


我认为这是有效的。我已经看到许多新开发人员在直接假设是语言/编译器/解释器时会自动将其归咎于他们。PHP在新开发人员中所占的份额远远超过其公平份额,因此它可能是相关的。
Draemon

1
程序员的错误总是。只要您使用有关的语言/平台成功完成了一个实现。维基百科在其他数千种中脱颖而出。PHP可能有其缺点,但其成功不可否认。
kprobst 2010年

2
@Felix:很多人都将PHP归咎于站点X或Y,这很明显是程序员的错。PHP完成了您告诉它要做的事情,这并不神奇,因为没有自己的想法。
AntonioCS

但是,一个好的PHP开发人员应该能够回答这个问题的意义在哪里呢?每个优秀的程序员都知道,如果某件事不起作用,那很可能是他的错,而不是语言的错。而且,如果有人责怪PHP,您仍然可以说:“嗯,这是一种专家语言” :-D
Felix Kling

3
但是php神奇的:magic_quotes_gpc
Draemon

6

转义用户输入的最佳做法是什么?(这个问题似乎经常出现)


10
当然,这是一个技巧问题。需要转义的输出,而不是输入。任何建议“清理”或转义$ _GET数组中所有内容的人都将“做​​错了”。
bobince 2010年

1
@bobince虽然我同意您要了解的部分内容,但是SQL注入又如何呢?或者,您是否认为这是输出的一部分?
乔丹·琼斯

2
@bobince错误。需要在进行数据库交互之前转义输入。当然,如果您像一个优秀的小型开发人员一样使用存储的proc,则这没有必要(除非您使用参数在SQL Server上生成并执行动态SQL,在这种情况下,您应该返回并在技术支持中工作)部门)
3Dave

6
这不是输入/输出的问题。你必须知道的数据是活动的背景下进入。如果是SQL查询,则必须以一种方式进行转义,如果是HTML输出,则必须以另一种方式进行转义,如果是URL,则必须以另一种方式进行转义,等等。我认为bobince突出显示的危险是如果您转义了数据在某个上下文的入口点,最终在以后用于另一个上下文中,您仍然容易受到攻击。
Draemon

3
使用一个框架为您做到这一点... db抽象层将保护您免受注入...正确的HTML渲染工程将转义输出...
back2dos

6
  • 调用$ array的“名称”元素时,是否正确?:

    • $array[name]
    • $array['name']

    两者通常都可以使用,但是只有引用形式正确。 define('name', 0);看着虫子飞。我看得太多了。

  • 您如何强制将表单元素提交为数组?

    将空括号添加到name属性:多个<input type="checkbox" name="checkboxes[]" />元素将被转换为服务器上的一个数组(例如$_POST['checkboxes'][0..n])。我认为这不是100%特定于PHP的,但是$_POST对于每个可能的'checkboxes'.$i元素,它肯定能胜过循环。

  • mysql_,mysqli_或PDO?

    这里只有一个真正错误的答案:mysql_库不执行准备好的语句,不能再为它的邪恶能力辩解。命名一个函数,每个执行的查询“ mysql_real_escape_string()”将被多次调用,这只是一针见血。


2
最后一点:这就是值数组上的foreach的目的。此外,您不应该直接使用mysql或mysqli。应该有一些抽象,以便您可以在某个时候切换到pgsql(例如)。
jmucchiello,2010年

@jmucchiello-同意foreach'ing和abstracting,这甚至不是PHP的错-这是mysql的C库中的函数名。也许有个人品味和古老的伤痕,但仍然有些笨拙,因为“当然很安全,我将其双引述” :)
tadamson 2010年

5

“您最喜欢的调试器是什么?”
“您最喜欢的探查器是什么?”

实际的应用程序/ ide /前端并不重要,只要它超出“记事本,echo和microtime()”范围即可。您不可能雇用十亿分之一的开发人员一直在编写完美的代码,并且他/她的单元测试发现了所有错误和瓶颈,甚至在错误发生之前,您都希望有人可以剖析和/或逐步执行代码并查找有限时间内的错误。(对于所有语言/平台来说都是正确的,但对我来说,似乎在php开发人员中技能水平还有些欠发达)


1
我已经在没有任何问题的编辑器中对PHP进行了很长时间的编程。不需要调试器。整个Linux内核的编写无需访问调试器。调试器是有帮助的,但完全没有必要。同样,仅当您确实有时间问题时才需要探查器。我为此使用了APD。但是我通常在php.ini中禁用了APD。
jmucchiello,2010年

调试器加快了工作速度,不仅因为您不手动打印值。答案:xdebuger(如果不使用zend studio)和zend调试器(如果您使用zend studio)
Yosef 2010年


4

我会问类似的东西:

a)缓存如何?

b)如何组织缓存?

c)您确定不执行额外的数据库查询吗?(在我用PHP制作的第一篇文章中,它是在foreach中的一个mysql_query,用于获取发表评论的用户的姓名……太糟糕了:))

d)为什么register_globals是邪恶的?

e)为什么以及如何将视图与代码分开?

f)“实施”的主要目的是什么?

在阅读了一些基础书籍之后,这些问题对我来说根本不清楚。我已经在几天\几周内通过网络上成千上万的常见问题解答找到了有关注入和csx,strpos的所有信息。但是直到我找到这些问题的答案,我的代码才真的很糟糕:)


我的英语不好。(英语不是我的母语)。所以,谢谢,会知道的。
本·乌斯曼

行动,这里就是这种“现金”。我的道歉。
本·乌斯曼

3

为什么永远不应该直接输出用户输入!

直接从GET打印数据之类的内容可能会导致跨站点脚本(XSS)漏洞。这就是为什么您应该始终始终首先通过htmlspecialchars()从客户端发送输入的原因。


以及SQL注入,跨站点请求伪造(CSRF),命令/ LDAP / XPath注入,包括注入,文件注入...
Kartoch 2010年

它不是特定于php的,而是适用于每个Web应用程序。
Residuum

2
它是非常特定于php的,因为PHP对于开发人员没有“默认安全”的精神。
卡托奇

@Kartoch:您不应假定任何系统都可以。即使它以该口号吹嘘自己。不要相信自己的安全性。
jmucchiello,2010年

@jmucchiello对不起,我不清楚:PHP是最易受攻击的网络语言之一,但我并不是说其他​​人都受到保护。
卡托奇


1

以下代码有什么问题?

$a = 2;
function foo()
{
    $a = 3;
}
foo();
echo $a;

答案?使用'global $ a;' 在函数的开头,因为除非使用了全局语句,否则函数中的$ a是本地的。
内森·奥斯曼

4
没错 它只是显示变量的范围:)
需要

但是从上下文可以明显看出,结果并非预期的。
内森·奥斯曼

唯一的问题是foo需要返回$ a。除此之外,您不能假设其他任何错误。
Chuck Burgess 2010年

3
更改问题和代码。而不是说“以下代码有什么问题?” 将其更改为“ $ a的结果是什么,为什么?” 将代码更改为以下内容:$a = 2; function foo() { $a += 3; return $a; } $a = foo(); echo $a;
Chuck Burgess
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.