开发强大的应用

时间:2011-03-17 16:50:06

标签: php oop

我注意到有一些功能,例如is_int()isset()file_exists()functions_exists(),它们在某种程度上非常有用。当我编写一些代码时,我总是会想到可能发生在我网站上的所有不好的事情,但有时候我会遇到以下问题:

  

等等,这个变量在PHP文件中设置;这意味着没有人能够编辑它,对吗?如果这个"用户"可以编辑它我会遇到很多麻烦,因为它可以管理PHP文件。

  

这是否真的值得继续检查应该存在的文件?

让我们考虑下面的例子,它本身没有意义,但会帮助我让你理解我在说什么。 PS:我故意夸大了代码。

的config.php

$doActions = true;

的functions.php

function getID() {
    return $_COOKIE['userid'];
}

class eye {
    public static function see() {
        // gain the object the user is looking at
        return $object;
    }
}

的index.php

class viewer {

    private $poniesSeen = 0;

    public function __construct() {
        /* Magic ponies are created here */
    }

    public function sawAPony($id) {
        if (file_exists('config.php')) {
            if (isset($doActions)) {
                if (is_bool($doActions)) {
                    if ($doActions) {
                        if (file_exists('functions.php')) {
                            if (function_exists('getID')) {
                                $id = getID();
                                if (!empty($id)) {
                                    if (!is_int($id)) {
                                        settype($id, 'int');
                                    }

                                    if (class_exists('eye')) {
                                        if (method_exists('eye', 'see')) {
                                            $o = eye::see();
                                            if (is_string($o)) {
                                                if ($o = 'pony') {
                                                    if (isset($this->poniesSeen) and is_int($this->poniesSeen)) {
                                                        ++$this->poniesSeen;
                                                        return true;
                                                    } else {
                                                        return false;
                                                    }
                                                } else {
                                                    return false;
                                                }
                                            } else {
                                                return false;
                                            }
                                        } else {
                                            return false;
                                        }
                                    } else {
                                        return false;
                                    }
                                } else {
                                    return false;
                                }
                            } else {
                                return false;
                            }
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
}

现在,我认为,应该保留哪些条件以及因为它们根本没有意义而扔掉的东西?我为什么不检查它们,我为什么要这样做?关于这种痴迷是否存在黄金法则?

9 个答案:

答案 0 :(得分:6)

这就是为什么语言带有错误消息(通常)。如果出现问题,它不会只是默默地崩溃,它会告诉你。所以你可以对你认为应该永远是真实的东西作出合理的假设,如果由于某种原因它不是真的,你会被告知。

以下检查无用,IMO:

  1. file_exists - 如果文件名已知并且您将其放在那里。如果参数是变量,那就没问题。
  2. is_boolis_int等。如果您坚持类型正确,请使用===进行比较。我用过的唯一一个是is_array
  3. function_exists之类的 - 如果您知道该文件存在,并且您将该函数放入文件中,则可以安全地假设该函数存在。同样,有一些特殊情况,这个功能很有用 - 你的不是其中之一。
  4. isset在某些情况下非常有用,例如检查数组是否包含给定键的非null值,或者是否在$ _REQUEST中传递了参数。还有其他检查方式不涉及isset,但这不是我的观点。

    如果你可以合理地期望你的断言应该一直都是真的,那么你需要做一个数据损坏或者很大的错误才能使它变错,不要费心去检查。如果在一百万次尝试中出现问题,那么您可以捕获错误并在下次修复它。代码可读性的成本太高了。

答案 1 :(得分:4)

一般来说,我谨慎地使用这些检查,原因很简单,就是避免产生如上所述的代码。

实施例。

请勿检查您自己创建的文件是否存在。检查是否存在您可能尝试打开以进行写入或读取的用户文件。

当涉及到类型检查时,再次检查不会改变的事物的类型。检查表单元素之类的用户输入的类型。如果一个函数需要一个int然后检查它得到一个....前提是它有可能没有得到一个(用户写了他的名字或其他东西)

答案 2 :(得分:2)

这总取决于您的申请。

这样做没有任何意义:

$foo = 3;
if (is_int($foo) && $foo > 3)
  // ...

然而,任何来自外部来源的东西都应该得到很好的检查。即使它来自数据库,你认为所有数据都是安全的,如果某些事情可能走错方向,请深入思考。

因此,检查并不总是必要的。花点时间思考是否有必要进行检查是可取的。


一条黄金法则:Anything that can go wrong, will go wrong (eventually)

答案 3 :(得分:1)

如果确实需要进行大量的检查,请反转检查并在失败后立即返回,如下所示:

public function sawAPony($id) {
  if (!file_exists('config.php')) {
    return false;
  }

  if (!isset($doActions)) {
    return false;
  }

  // etc
}

这样你可以避免过度缩进,并尝试匹配大括号。理想情况下,您可能需要找到一种方法来重构所有检查。

在我看来,将所有内容与&&联合起来不会使代码更具可读性。

至于您需要哪些检查 - 您应该检查您的代码所依赖的任何内容,前提是您正在运行的系统无法保证这些内容。

始终检查无法控制的内容(尤其是用户输入,外部服务等)。如果您发现自己在很多地方添加了这些检查,请在某处重构它们。

答案 4 :(得分:1)

查理,

你所做的事情是多余的,没有必要。 PHP会为你处理大部分内容(即确保字符串中的数字被解释为一个整数,然后检查它是否只是在变量甚至没有在它们之间使用时只有几行)

这类似于不仅仅穿上衣服外出,而是在防弹车中使用全套太空服,并驾驶10英里远离汽车撞到的任何物体。

如果您的代码不仅仅是例如并且实际上有目的或有意义,我可以在外面为您重写它,它会告诉您正确的“安全防护”类型,但是我无论如何都要试试。

include("config.php"); 
include("functions.php"); 

class viewer {

    private $poniesSeen = 0;

    public function __construct() {
        /* Magic ponies are created here */
    }

    public function sawAPony($id) {
        $object = eye:see(); 
        if($object == 'pony') {
            $poniesSeen++; 
            return true; 
        }
        return false;    
    }
}

LOL。我想就是这样。那太好了。担心你的程序的逻辑,而不是程序的程序(如果这有任何意义,可能没有)。

干杯,

答案 5 :(得分:1)

它是一个PHP设计/编程风格问题。许多网络程序员喜欢使用可能与否的变量,可以事先声明并分配初始值(“动态类型”,我认为是这样)。

例如,这些变量可以是任何类型,或者很容易从一种类型转换为另一种类型(“string”到“int”)。 PHP和其他Web编程语言允许这样做。

当我编写自己的PHP文件时,我通常编写类似于静态类型语言的代码:


mylibrary.php

// expects a 0 | 1 (boolean) query-string parameter, even if not present ?
// "pseudo-declare it"

/* bool var */ $myOption = false;
$temp = $_REQUEST['option'] ;
if ($temp != NULL) {
  $myoption = ((int)temp == 1);
}

/* int */ function myFunction () {
  // simulate variable declarations,
  // and initial values, like other languages
  /* int var */ $result = -1;

  global /* bool var */ $myOption;

  /* bool var */ $doSomething = false;

  while (...) {
    ...
    if ($myOption) {
      $doSomething = true;
    }
    ...
  }

  return $result;
}

这种详细的编码,允许我避免所有存在或类型检查功能。

答案 6 :(得分:0)

我没有查看您的所有代码。但是要回答你的问题,如果你完全控制你的变量并且除了你以外没有其他人在你的系统上工作,并且它不接受任何外部用户输入你可能考虑跳过这些检查。

但编程的整个问题是我们永远无法确定我们的应用程序将要通过什么。

经验法则是,如果您希望您的应用程序在未经审查的情况下发生灾难性故障,那么您进行检查。你认为这不值得吗?

确实,PHP文件中创建的变量不能由用户控制。但是2或3级下来还是上升呢?当它与用户输入接触,然后在其他地方接收到你的方法?这就是为什么最好验证并键入检查并为所有变量分配默认值。

最后,安全比抱歉更好。

答案 7 :(得分:0)

: - d

首先指出您的应用程序存在严重问题(例如需要删除类的旧版本文件)。如果发生类似这样的事情,只需向用户提供一个好的(或有用的或两者)500页面并提醒自己。否则你可能会在以后的某个地方崩溃,这将更难调试。

  • file_exists可以替换为 require "file"
  • class|method|function_exists可以省略,如果你不能没有它们而你希望它们在那里
如果您期望在代码中设置一些变量(只需在开发环境中打开通知),则再次不需要

isset

在处理输入时(例如,当您期望一个数字时),更改数据类型非常有用。

这一切都假设您可以很好地控制正在执行的代码。如果有人不信任可以修改你的部分代码,那么祝你好运。

答案 8 :(得分:0)

首先,我们无法在任何小项目中检查条件。如果你需要大量的检查,首先要整齐地写下它们。然后考虑根据您可以一起检查的条件重构代码,例如

if(a!=0){
   if(b!=0){
      // do this
   }

} 可以重新写入

if(a!=0 && b!=0) {
   //do this
}

(为了方便起见,我太简单了)。