【问题标题】:php and mysql, best practicesphp 和 mysql,最佳实践
【发布时间】:2010-07-29 16:45:39
【问题描述】:

我今天开始使用 php 和 mysql。基本上,我所拥有的是一个空白页面,其中包含我通过在数据库中查找 id 来填写的片段。所以在我的主页上,我有一个如下所示的网址:

<a href="content/display.php?id=id1">

然后在我的 display.php 我有这个:

<?php
    include '../includes/header.php';
    $id = $_GET['id'];
    $mysqli = new mysqli('localhost','username','password','dbname');
    if($result = $mysqli->query("SELECT * FROM portfolio WHERE id='".$id."'"))
    {
        while($row = $result->fetch_object())
        {
            $head = $row->head;
            $img1 = $row->img1;
            $img2 = $row->img2;
            $img_url = $row->imgurl;
            $img_thumb = $row->imgthumb;
            $vid = $row->vid;
            $swf = $row->swf;
            $url = $row->url;
            $url_text = $row->urltext;
            $text = $row->text;
        }
    }
    else echo $mysqli->error;
?>

这是一个稀疏表,并非所有这些字段都有信息(许多可能为空)。基本上它们包含文件名,然后在 html 中我有如下代码:

if(isset($img1))
                    {
                        echo '<img src="images/'.$img1.'" />';
                    }

几个问题,

  1. 这是最好的方法吗?
  2. 每次访问 display.php 时,我都会重新打开数据库连接,对吗?这可不好...
  3. 我选择将文件名放在数据库中,而不是整个路径名,甚至是实际文件本身,我想如果我更改文件名,我可以进入数据库并更新它我要更改的文件。如果我更改路径,我可以在 html 中更改一次。这是最好的主意吗?

谢谢!

【问题讨论】:

  • (重新)打开数据库连接是常见的做法,它应该没什么大不了的。我确实想知道为什么您要将对象的每个属性都放在另一个变量中?
  • 我想所以我不必将整个网站包装在那个 while 循环中......我想我可以做到这一点

标签: php mysql mysqli


【解决方案1】:

1) 不,尽管这是最简单的开始方式。在您对基础知识感到满意之后,您应该花一些时间考虑应用程序结构的不同方法。最重要的规则是分离关注点。不要将数据库代码与业务逻辑代码与演示代码混为一谈。但就像我说的,这不是你在第一天就应该担心的事情。现在只学习基础知识。

2) 实际上没有其他方法。对于 Web 应用程序,来自浏览器的每个请求都类似于单独运行的应用程序。有可能使用所谓的持久数据库连接,但就像前一点一样,这是您不应该在第一天处理的事情,因为它们需要您的 Web 服务器的特定配置。暂时只使用普通连接。

3) 这是非常明智的想法。您还可以将图像路径定义为 PHP 常量,这样在需要更改时,您只需更改这个常量即可。

4) sAc 在他的回答中所说的非常重要。了解 SQL 注入以及如何防止它们。

【讨论】:

  • 1) 我熟悉 MVC 方法。但是,我对 PHP 还很陌生。我使用了 Struts 2 并将框架放在一起以促进分离业务、数据和表示。为了将来参考,我想了解更多关于如何在 php.ini 中执行此操作的信息。有什么好的指南可以开始吗?谢谢!
  • 哦,在那种情况下,情况就完全不同了 :) 有几种用于 PHP 的 MVC 框架,它们在实现细节上差别很大。一个非常流行的是 Zend Framework,许多人说它实际上是松散耦合类的集合。另一方面,有像 Symfony 这样的框架实现“按约定配置”模型。您肯定会找到适合您需求的产品。
  • @Col。弹片我对这个网站和回答协议还是有点陌生​​。我没有意识到我只能选择一个答案。
  • @Mchl 这些设置需要很多时间吗?每当我想建立一个 struts 2 项目时,我需要配置一堆东西,因此对于像个人网站这样的相对较小的项目,我认为这不值得我花时间。另外我想练习我的php!当我在 struts 2 中开发时,我可以将 .war 部署到 tomcat 服务器,它就可以工作。对于带有 php 的服务器,您使用的服务器是否必须已经安装了框架?谢谢!
  • PHP 世界与 Java 世界有点不同。在 PHP 5.3 中使用了 phar 文件格式,理论上它可以提供与 .war 相同的好处。我从未见过它在使用中。要在服务器上安装 PHP 应用程序,您通常会上传应用程序包含的所有文件。这可能是一项乏味且棘手的任务,因此版本控制和持续集成工具有很大帮助。 Zend Framework(可能还有其他的)有一个命令行工具,它为你做了很多“设置一个新项目”的工作。您在几秒钟内就拥有了一个功能性应用程序。虽然它只显示一个静态页面;)
【解决方案2】:

您很容易受到SQL injection 的攻击,请正确键入您的变量:

$id = (int) $_GET['id'];

使用mysql_real_escape_string之类的函数甚至更好用:

【讨论】:

  • 我对 jdbc 使用了准备好的语句,但对 php 没有使用,所以我有点熟悉。我会检查一下。由于我的 id 不是 int,这就是 mysql_real_escape_string 的用途吗?谢谢
  • @JPC:是的,你可以使用what mysql_real_escape_string
【解决方案3】:

已经提到了 SQL 注入和准备好的语句。除此之外还有:

else echo $mysqli->error;

将其更改为:

else trigger_error($mysqli->error,E_USER_ERROR);

你为什么问?因为访问者应该不知道您的数据库,并且无法修复错误,所以他们根本不应该看到它。这样,您可以安全地在 display_errors 开启的情况下进行开发,而在实时站点上 display_errors 已关闭,而您在错误日志中的 log_errors

【讨论】:

  • 错误记录在哪里?我必须在某处配置 display_errors 和 log_errors 吗?
  • 我认为实际上最好的方法是将所有错误转换为 ErrorExceptions,如此处所述 php.net/manual/en/class.errorexception.php ,但这又是一个更高级的话题。
  • @Mchl 异常更多的是错误处理,而 Wrikken 则谈到错误跟踪。那是不同的世界,不干涉。实际上,您可以在同一个脚本中同时使用两者。
  • @JPC :是的,配置 display_errorslog_errorserror_log(在 php.ini、网络服务器的虚拟主机配置或 .htacces 文件中)。 @Mchl:如果您的应用程序旨在处理另一个位置的错误,则 ErrorExceptions 是可以的,因此它应该“上树”。如果在这种情况下所需的结果是“如果查询失败则不打印任何内容”,则无需抛出错误条件,因为您正在原地处理它。但是当 OP 正在学习 a.t.m 时,了解异常以及如何使用它们确实是明智的。还有 Shrapnel 上校说的 :)
【解决方案4】:

看起来你对自己想做的事情有很好的把握。我不知道你有多少开发背景,但开始学习 php 中的 MVC 是个好主意,比如 CakePHP、Fuse,甚至 Zend Framework(呜呜!!!)。通过预定义所有基本的数据库接口、模板处理、会话处理,我将节省您在更强大的应用程序上的时间,并让您担心更高级别的问题,例如午餐吃什么! :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-28
    • 2011-03-06
    • 2012-05-22
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    相关资源
    最近更新 更多