PHP + MySQL 的魔力

可以肯定地说,如今几乎每个最新网站都使用某种形式的内容管理系统 (CMS)。虽然有很多很棒的免费选项可以为我们提供一个 CMS 来为网站提供动力(WordPress、Drupal 等),但窥视一下引擎盖并了解这些系统的工作原理并不会有什么坏处。
为了开始我们作为后端开发人员的旅程,我们将创建一个简单的 PHP 类,它将
- 创建一个数据库
- 连接到数据库
- 显示包含两个字段的表单
- 将表单数据保存到数据库
- 从数据库中显示已保存的数据
这个类旨在让您了解 PHP 和 MySQL 如何协同工作,并展示 CMS 的基础知识。我将跳过对一些非常基础的编程内容的解释,所以如果您在任何时候感到迷茫,请查看课程 Diving into PHP 并给自己上一节关于 PHP 的速成课程。不过,我保证不会让任何人迷路。
构建类
第一步是将类简单地放在名为“simpleCMS.php”的文件中,以便我们有一个可以参考的路线图。
<?php
class simpleCMS {
var $host;
var $username;
var $password;
var $table;
public function display_public() {
}
public function display_admin() {
}
public function write() {
}
public function connect() {
}
private function buildDB() {
}
}
?>
如您所见,我们正在创建一个包含四个变量和五个方法的类。我选择使用 PHP 的 面向对象方法,因为它在大型项目中可以生成更清晰的代码,并且在我看来,这是一种良好的实践。
变量
在这种情况下,所有四个变量都用于连接到数据库:$host
、$username
、$password
和 $table
为我们提供了一个路径和访问权限来访问服务器上的数据库。目前,我们将它们留空并继续进行数据库构建,该数据库由方法 buildDB()
构建。
构建数据库
private function buildDB() {
$sql = <<<MySQL_QUERY
CREATE TABLE IF NOT EXISTS testDB (
title VARCHAR(150),
bodytext TEXT,
created VARCHAR(100)
)
MySQL_QUERY;
return mysql_query($sql);
}
此函数运行一个 MySQL 命令来检查数据库,查看testDB是否存在。如果存在,它只传递一条成功通知;如果不存在,它将创建我们的表并将三个列分配给它以保存数据。
连接到数据库
现在我们有了构建表的函数,让我们创建连接到数据库的函数。
public function connect() {
mysql_connect($this->host,$this->username,$this->password) or die("Could not connect. " . mysql_error());
mysql_select_db($this->table) or die("Could not select database. " . mysql_error());
return $this->buildDB();
}
我们调用 mysql_connect() 来连接到我们的数据库,然后调用 mysql_select_db() 来确保我们将数据保存到正确的位置。这两个函数都伴随有 die()
命令,该命令本质上是说:“如果该函数失败,则停止执行该脚本并显示一条消息。”
我们的 connect()
函数连接到数据库并让我们指向正确的方向,然后运行我们的 buildDB()
函数。还记得我们 MySQL 命令中语法尴尬的“IF NOT EXISTS”部分吗?因为我们将每次加载页面时运行此函数,所以我们必须确保我们不会在每次函数调用时覆盖我们的数据库,这就是该短语的用途。
构建表单
所以,我们有一个数据库。现在我们只需要往里面填东西!
public function display_admin() {
return <<<ADMIN_FORM
<form action="{$_SERVER['PHP_SELF']}" method="post">
<label for="title">Title:</label>
<input name="title" id="title" type="text" maxlength="150" />
<label for="bodytext">Body Text:</label>
<textarea name="bodytext" id="bodytext"></textarea>
<input type="submit" value="Create This Entry!" />
</form>
ADMIN_FORM;
}
同样,这是一个非常简单的函数。当被调用时,它只是返回 HTML 标记来创建我们的表单。但是,您会注意到,在 form
元素的 action
属性中,我使用了变量 $_SERVER['PHP_SELF']
。这本质上是一个引用您当前使用的文件的快捷方式(在本例中,它是 display.php
)。如果您将在整个网站中重复使用您的代码,并且不想为每个页面重新编写此函数,这将非常有用。
我还要花点时间来讨论一下我用于返回 HTML 的方法。它是一种在 PHP 中使用的格式,称为 HEREDOC 语法,而且我非常喜欢它。
HEREDOC 的主要优势是它允许您在输出中包含格式。对于像我这样对杂乱的源代码感到不满的人来说,这非常有用。您可以在 PHP 手册 中了解有关 HEREDOC 语法及其同类的更多信息。
将数据保存到数据库
我们的表单将允许我们输入信息,那么我们如何保存它呢?这就是我们的write()方法发挥作用的地方。
public function write($p) {
if ( $p['title'] )
$title = mysql_real_escape_string($p['title']);
if ( $p['bodytext'])
$bodytext = mysql_real_escape_string($p['bodytext']);
if ( $title && $bodytext ) {
$created = time();
$sql = "INSERT INTO testDB VALUES('$title','$bodytext','$created')";
return mysql_query($sql);
} else {
return false;
}
}
让我们从函数调用本身开始——我们向它传递了一个变量,而之前我们还没有这样做。我们的变量 $p
将保存通过 post 方法 从我们的表单发送的信息。
进入函数后,我们首先使用一个 条件语句 来检查在提交表单之前是否设置了 title
值,如果设置了,我们将 $title
变量设置为 $_POST['title']
值(注意:我们使用的是函数 mysql_real_escape_string() 作为对潜在危险输入的预防措施,这一点在构建任何允许用户输入信息的程序时都要牢记)。如果 $_POST['title']
未设置,我们将跳过此行,使 $title
变量保持未设置状态。
这个过程会对我们的第二个输入重复,然后检查两个变量以确保在保存到数据库之前没有为空。如果两个变量都已设置,我们将使用当前的 Unix 时间戳 设置 $created
变量,我们将在将来查看条目时使用它按时间顺序排序条目。
现在我们有三个变量,并且由于我们已经运行了检查,我们知道所有三个变量都不为空。现在我们可以编写我们的 MySQL 查询,该查询将把条目保存到数据库中!
从数据库中显示信息
现在我们有了将信息放入数据库的方法,我们需要创建一种方法来将该信息取回。这就是 display_public()
发挥作用的地方。这是我们最复杂的方法,所以让我们花点时间真正弄清楚内部发生了什么。
public function display_public() {
$q = "SELECT * FROM testDB ORDER BY created DESC LIMIT 3";
$r = mysql_query($q);
if ( $r !== false && mysql_num_rows($r) > 0 ) {
while ( $a = mysql_fetch_assoc($r) ) {
$title = stripslashes($a['title']);
$bodytext = stripslashes($a['bodytext']);
$entry_display .= <<<ENTRY_DISPLAY
<h2>$title</h2>
<p>
$bodytext
</p>
ENTRY_DISPLAY;
}
} else {
$entry_display = <<<ENTRY_DISPLAY
<h2>This Page Is Under Construction</h2>
<p>
No entries have been made on this page.
Please check back soon, or click the
link below to add an entry!
</p>
ENTRY_DISPLAY;
}
$entry_display .= <<<ADMIN_OPTION
<p class="admin_link">
<a href="{$_SERVER['PHP_SELF']}?admin=1">Add a New Entry</a>
</p>
ADMIN_OPTION;
return $entry_display;
}
在从数据库中读取时,需要注意的第一件事是 PHP 和 MySQL 如何相互作用。首先,我们向数据库提出一个问题(查询),数据库会用一个结果(资源)来回答。但是,在使用几种将结果中的信息“获取”或组织成可使用形式(数组)的方法对其进行解码之前,这个结果并不真正有用。
在上面这个函数中,我们首先要做的就是在变量$q
中设置我们的查询。MySQL 中的星号 (*) 操作符表示“所有”,所以我们的查询要求数据库从testDB
表中的条目中选择所有内容,并按时间倒序排列,限制为返回的前三个条目。
现在查询已经定义好了,我们使用函数mysql_query()将它发送到数据库。结果资源存储在变量$r
中。这里就有点棘手了。
现在我们运行一个条件语句,它说:“如果mysql_query()
没有失败,并且如果返回的条目数量大于零,就处理结果,否则就显示一个默认消息。”
如果$r
包含来自数据库的条目,我们现在必须“提取”这些数据。来自数据库的信息以数组形式返回,其组织方式类似于数据库表本身。函数mysql_fetch_assoc()将获取资源并将每个条目分解为一个关联数组(这意味着当我们将mysql_fetch_assoc()
的结果保存到变量$a
中时,来自条目的数据可以通过数据库中的列名访问,例如$a['title']
)。
然而,mysql_fetch_assoc()
一次只能给我们一个条目。为了获取所有返回的条目,我们必须使用一个while循环。本质上,我们是在说:“当$r
还有我们尚未使用过的值时,获取下一行条目并对它执行以下操作。”
在这种情况下,我们将检查条目以确保数据已返回,然后使用stripslashes()删除我们在使用stripslashes()
将信息保存到数据库时添加的反斜杠。之后,我们只需将变量包装在一些HTML中,瞧!我们得到了可以显示在屏幕上的内容!
作为最后一步,代码在底部添加了一个链接,允许用户添加条目。值得注意的是在while
循环中以及在创建“添加新条目”链接时使用的“.=”操作符;一个函数只能返回一个变量,所以我们需要将新信息追加到现有变量中。如果我们只使用等号(“=”),我们将覆盖现有数据,最终只会得到一个指向表单的链接,而没有内容。
所以,你现在已经写了你的第一个CMS类!你可以轻松地将数据写入数据库和从数据库中检索数据。剩下的就是去尝试一下了!
使用这个类
为了使用我们的类,我们需要创建一个单独的文件。我将把它命名为“display.php”,我将在主网页文件夹中保存它,我们的类保存在主文件夹中的“_class”文件夹中,命名为“simpleCMS.php”。首先,我们只需设置一个带有普通HTML的文档。
<!DOCTYPE html>
<html lang="en">
<head>
<title>SimpleCMS</title>
</head>
<body>
</body>
</html>
为了使用我们的类,我们只需在body标签之间插入一小段PHP代码即可
<?php
include_once('_class/simpleCMS.php');
$obj = new simpleCMS();
$obj->host = 'database.host.net';
$obj->username = 'DB1234567';
$obj->password = 'DBpassword';
$obj->table = 'DB1234567';
$obj->connect();
if ( $_POST )
$obj->write($_POST);
echo ( $_GET['admin'] == 1 ) ? $obj->display_admin() : $obj->display_public();
?>
首先,我们必须使用include_once()函数包含这个类。然后,我们必须实例化我们的对象,以便我们的代码知道发生了什么。第三,我们设置了我们在本教程开头谈到的所有那些变量。你必须用从你自己的服务器或托管公司获得的信息替换所有这些值。第四,我们使用connect()
方法连接到数据库。
连接到数据库后,我们检查是否有任何$_POST
信息存在。这是因为我们使用同一个文件来输入、处理和显示信息。如果通过$_POST
传递了任何内容,我们将运行write()
函数来验证它并将其保存到数据库中。然后,我们使用一些简写技巧来运行一个条件语句。从本质上讲,我们是在说,“如果$_GET['admin']
设置为1,那么使用display_admin()
显示表单,否则使用display_public()
显示存储的条目。”
就是这样!一旦你对它有了感觉,这种基本的编程将让你开始对构建的网站行使完全控制权,无论你决定深入研究并构建自己的CMS框架,还是仅仅通过例如编写一个WordPress插件来改进现有的CMS。
真的,当涉及到现代网页设计时,你至少应该对幕后发生的事情有一些了解——了解一个网站如何工作,将更有助于你设计出形式和功能更流畅集成的网站。此外,将PHP和MySQL添加到你的简历中肯定不会损害你的信誉……
重要提示
此代码仅用于演示目的。评论中指出了几个安全漏洞,我在本教程系列的第二部分 编辑说明:本系列已经没有第二部分了。Jason 建议他的书PHP for Absolute Beginners 作为最佳实践资源。中进行了处理。不过,我还是强烈建议不要在没有进一步测试的情况下将其用于生产网站。
我已经对安全问题进行了处理,但可能还存在其他问题。有关安全风险和安全PHP代码的更多信息,请参见此处。请在将此代码部署到服务器上之前仔细阅读,以避免潜在的安全漏洞。
太棒了!这正是我个人需要开始使用一些适当的PHP脚本的!再次感谢您提供的优质内容:)
很棒的文章,Chris!
但只做一个小小的修正...HEREDOCS 以<<< 而不是 >>> 开头
真是太尴尬了...
这就是我使用无差别查找和替换的结果。感谢提醒!
没事...没关系
谢谢!这正是我一直以来所需要的!
非常棒的教程!我真的很喜欢你最近在CSS-Tricks上发表的内容质量,太棒了。我一定要跟着做,把它作为一个基本CMS,用于想要宣传网站的客户。
从我的角度来看,一个很好的后续内容是,如何以同样的格式调整这个简单的CMS来支持多个页面。
正在更新我客户的网站,使其更容易在办公室更新。这将完美地工作!非常感谢!
出于安全考虑,请使用sql参数...
哦,太棒了,我刚开始学习PHP,一直在寻找这样的东西!谢谢!
很棒的教程!这是一个很好的简单示例,但背后却蕴含着高级概念。在将来,你能否将其扩展到包括更新和删除功能?
–Brenelz
我还没有真正抽出时间仔细阅读它...但从略读来看,这篇文章很棒。这正是目前所需要的...对PHP和CMS开发的简单、逐步的说明。干得好,Chris。感谢您的努力。
很棒的教程!
我认为在使用OOPHP时应该指出/考虑一些事情。
只有正确使用类才能使代码变得更好。这个类与用过程代码完成的功能相比,并没有好多少。基本上,它太宽泛了。通常情况下,你会将所有这些功能分解成多个类,并在CMS类中使用它们。
class DB_MYSQL(用于对MySQL数据库执行CRUD操作的函数)
class DBConnect(用于连接到数据库的函数——应该是单例模式)
类模板(用于显示表单的函数)
类验证数据(用于过滤/验证用户输入的函数)
感谢您精彩的写作!
很棒的教程,期待更多关于 cms 和 php 开发的教程!
漂亮!
就在我想要开始学习一些 PHP 的时候。很好的开始方式。
感谢这个教程,请继续发布这种类型的教程。
我的天哪,使用框架!我同意任何 PHP 开发人员都可以在 5/10 分钟内完成这项工作,但拜托,为什么要浪费这种时间?这就是为什么 PHP 应用程序会变成难以维护的、充满模糊且无文档代码的庞然大物…
我知道,天哪,为什么要学习一些已经完成的东西。这就是为什么我永远不会学习弹奏乐器,因为已经有很多专辑可以让我听了。
很棒的教程是为了帮助人们“学习”…经验丰富的开发人员也必须从某个地方开始。
哈哈哈,克里斯回答得很好…@Hafseflats 说的是真的,WordPress、Joomla 有助于内容管理,但有时客户需要一个特定的网站,而 WordPress、Joomla 等根本帮不上忙。这是提高我们工作效率的最佳方式,而且非常专业。
你说得对,框架。那真是个好主意。我的意思是,PHP 框架只有 1 MB 左右,而这个页面这么短,只有 4 KB。为什么要在地球上节省带宽和硬盘空间?太疯狂了。
另外,为什么要学习东西是如何工作的?因为你知道,编写 CMS 工具和框架的人天生就会使用 CMS 工具和框架。
感谢 Jason Lengstorf,这个教程很棒,因为它只做了最基本的事情,我已经读过几本书,他们总是做关于如何制作 CMS 的教程,但它们总是冗长乏味,让初学者感到困惑。我个人使用 WP 和 SilverStripe,但这确实是关于如何与数据库交互的绝佳例子。
我同意 hatseflats 的观点。
@hatseflats – 为什么这么消极?使用框架有很多缺点,它们绝非完美 – 此外,你从框架中什么也学不到,而且我敢肯定 99% 的人访问 css tricks 是为了学习新技能。
同意。
我也同意,但是,使用现有的框架可能并非坏主意。一个现实世界的 CMS 非常复杂,就像 hatesflats 所说,它们可能会变成难以维护的庞然大物。
然而,掌握 PHP 和 MySQL 以及 CMS 的工作原理,在使用 WordPress 等平台时会让你拥有很大的优势,或者如果你需要创建一个小型网站或小部件,而它可以从数据库中获益。
对所有其他人,非常感谢大家的积极反馈!当然,还要特别感谢克里斯运行了这个教程。我将采纳评论中的一些建议,并编写后续教程,所以如果您不介意,请访问我的网站或关注我的 Twitter (@jasonatennui),以查看这些教程。
再次感谢!
现在就关注你!再次感谢您提供的精彩教程,请继续发布更多教程!
我不喜欢框架。它们臃肿,而且试图为你做所有事情。我会编写自己的代码,更轻便,谢谢。:)
在尝试自己构建之前使用框架或 CMS 的问题在于,你永远无法学习在好的框架中寻找什么。尝试掌握数百个 PHP 包是一项艰巨的任务,而通过自己动手编写代码,你可以大大缩小选择范围。
我真的很感谢你!今天,我已经将我新学的知识直接应用到我们新的内部网上!问候
我真的很喜欢这个,期待阅读更多,也许编辑并加入一些 ajax,例如包含所有内容的小教程。
下载代码是否已更新,并修复了之前评论中提到的错误?
不错的教程。让我们在第二部分中加入一些用户身份验证。:)
很好的教程。谢谢..
感谢您提供的精彩教程。稍后我会仔细研究。我如何使用这种方法编辑我创建的帖子?
非常棒的教程。我非常希望看到更多部分:用户身份验证、扩展发布内容,以及可能为管理屏幕提供一个皮肤。我很期待。:)
这是非常基本的 OOP,你能否制作更多类似的教程,但进一步扩展?
不要点击演示按钮
错误,你需要修复演示链接……我收到一个消息框,告知我:糟糕!…CSS-tricks.com
可能需要看一下?!!!
问题已修复。一些混蛋在进行大量 JavaScript 注入。
他们来自 http://www.totse.com/en/_feedback/feedback.html – 以防任何人想过去告诉他们他们是多么酷。
不打算在这里重蹈覆辙,但这不就是一个使用框架的原因吗?这里的优势在于,一些非常非常聪明的人(比你我聪明)已经考虑过人们可能黑入你网站的数百种方法。通过使用框架,你可以利用这些聪明才智。
我知道这只是一个非常简单的例子,但你的网站在几分钟内就被黑了。这个 CMS 示例非常好,编写得很出色,是 PHP 的一个很好的入门教程,但如果要继续走这条路,很快就会遇到会话管理、SQL 注入、XSF、会话固定等等问题。如果可以让框架来处理这些,而你只需要处理添加功能和良好设计,那不是很棒吗?
让我们面对现实吧,WordPress、Drupal 和其他博客都是框架。没有人抱怨它们的臃肿。
所以,所有代码高手:与其只是随意发表一些关于不喜欢框架臃肿,或者说你永远不会通过使用框架来学习编程的评论,不如给人们一些准确的信息,让他们学习。
话虽如此,如果你喜欢这个教程,你应该查看 cakePHP 关于如何创建博客的教程,看看它与直接编码方法相比如何。
或者你可以编写安全的代码……
这是一个例子,大家,是专门为让没有经验的程序员学习某些东西而设置的。我怀疑我们第一个应用程序是否,例如,是 SQL 注入安全的,但有一天我们了解了它,并确保它不会发生在我们身上。如果你需要知道所有关于编写一个良好且安全的框架的内容都在这里,它就不再是一个教程,而是一本书,甚至是图书馆。
哦,我尝试点击了“确定”按钮……它无法工作。?!非常令人沮丧
很棒的教程,谢谢;)
我认为你应该对 JavaScript 注入做点什么。
是的,很棒!:D
像这样的教程真的在提升我的学习体验。感谢所有做出贡献的人。
感谢 Chris。这正是我想要用来构建我自己的 CMS 的东西。之前我用的是 文本文件 而不是 mySQL,它并没有完全按照我想要的方式工作。
感谢 Jason 和 Chris 提供了这个很棒的教程。:)
这应该可以修复所有 XSS :D
真正有用的是展示一种创建类别的方法,以及在它们自己的页面上显示的文章。
感谢 Chris 和 Jason 提供了这个教程。干得好。
P.S. 我很喜欢你从文章中链接的“这就是她说的”视频。它很棒,很有趣。
我忍不住……:)
再次感谢大家提供的宝贵反馈!
我正在做笔记,并且会发布关于用户身份验证、编辑文章以及使用 PHP 和 MySQL 进行 AJAX 的博客文章。还有其他人想看什么吗?
请务必访问我的 博客 并订阅 RSS 订阅源,以免错过它们!
我不介意看看如何使用 php 和 mysql 构建一个基本的图像插件。
太棒了!简洁干净。需要更多想法。非常感谢。
很好的教程,可以帮助我开始构建 CMS。我是一个经验丰富的 ColdFusion 开发人员,上周花了时间完全沉浸在 php 中,这样我就可以在更便宜的托管上快速创建更小的网站。我确实想要创建一个可重复使用的 CMS,以便可以轻松地将其放入未来的网站中。
感谢上帝,编写主要框架的人并没有仅仅依赖现有的框架。仅仅使用其他所有人已经做过的事情并不是获得更好的新东西的好方法。在现有的代码基础上不断改进是一回事,但偶尔从头开始是使用所有最新技术的最佳解决方案,这也是你学习的方式。
感谢您的教程。
您好,我非常喜欢这个教程,但我有一个问题。我刚开始学习网络开发语言,我想知道哪种语言更适合先学习?我正在考虑 PHP 或 Ruby on Rails?我知道 PHP 是一种脚本语言,而 Rails 是一种框架,为了理解另一种语言,哪种语言最适合先学习?
谢谢!:)
Ruby on Rails 稍微容易一些——我相信该项目的总体目标是简化后端开发。
PHP 会让你更好地理解“如何”,如果你想要的话。
感谢您的教程
您好,Chris。
我不知道你什么时候做的!你难道不睡觉吗?
无意冒犯,但我快速浏览了你的文章,发现很多地方我都有问题。
为什么你在每次页面加载时都执行 CREATE TABLE IF NOT EXISTS?这是一个无用的查询。创建它,然后存储它已创建的位置——或者手动执行。
display_admin() 表单。$_SERVER[‘PHP_SELF’] 不安全。可利用 XSS。使用 htmlspecialchars($_SERVER[‘PHP_SELF’], ENT_QUOTES) 或 htmlentities($_SERVER[‘PHP_SELF’]); 清理它。
如果 magicquotes GPC 处于开启状态,你希望在将 $_POST 中的项目插入数据库之前从它们中去除反斜杠。(在大多数情况下,magicquotes GPC 现在都会被禁用)
在插入新项目的 INSERT 查询中,最好指定要插入的字段。如果向表中添加另一个列(例如,使用默认值),那么你也需要调整查询。如果你明确命名列,则无需这样做。
mysql_num_rows 应该谨慎使用。在你的使用场景中,它很安全,因为你设置了非常低的查询限制。为什么?此函数会让 PHP 手动计算每一行。对于大型数据集,最好的解决方案是单独执行 COUNT 查询,或者更理想的情况是,在 while 循环中,如果处理了任何文章,就设置一个标志。(说到这,你只需要执行 if(!$entry_display) { … 无文章消息 }。
从数据库中获取数据时,不需要使用 stripslashes。特别是如果 magicquotes GPC 关闭,因为这会去除合法斜杠。
再次强调,$_SERVER[‘PHP_SELF’] 是被污染的。这一点在这里尤为重要,因为它是一个公开可访问的页面。在显示之前进行转义。
if($_POST) 是一个非常糟糕的检查方法。检查 $_SERVER[‘REQUEST_METHOD’] 是否为 POST,或者 $_POST 是否为空(if(!empty($_POST)) {)
抱歉,但我有一个问题,如果你要教别人如何使用编程语言,你需要做对,这样你就不会教导错误的实践。
感谢您指出脚本中的漏洞。在该系列的后续部分中,我会进行您提到的修复,以确保代码安全。
我还在学习,因此我为我的失误道歉。我向你保证,它们是无意的。:)
Jason Lengstorf 干得好!
我认为这篇文章写得很好,将对许多有抱负的网络爱好者大有帮助!
我最近(08 年 12 月)被委托为客户构建一个定制的网络应用程序。我知道我将不得不使用某种 CMS 框架,并创建、读取、更新和删除大量 CMS 框架无法完成的数据;因为项目的定制性质。
因此,我花了一周时间学习了 lynda.com(并非有意推广)上关于如何使用 PHP 和 MYSQL 构建 CMS 的非常棒的教程。现在,我更了解 PHP/MYSQL/CMS 的工作原理,并且能够轻松地编写一些我的第一个函数。**但是**,我认为如果我在项目之前阅读了这篇文章,会节省我很多时间。
你们干得好!
并非想泼冷水,但
display_public()
太糟糕了。在同一个函数中,你使用了数据访问、业务逻辑和模板逻辑。不要误会我的意思,你的文章可能对 PHP 新手很有趣,但它教授的是错误的实践。谨慎使用。感谢 Chris… 每个 PHP 初学者都会喜欢这个…
不错,这个教程中使用的图标集叫什么名字?我喜欢它们的外观!
在 popurls 上看到了它。
我喜欢 heredoc。嗯,在 Ruby 中。不过,它是一样的。Heredoc 真是太棒了。
Jason,好文章,非常感谢!我一直想构建自己的 CMS,但不知道从哪里开始。如果你能扩展它——构建一个更全面的 CMS——那就太好了。
在收到这篇教程的诸多好评后,我想我会开始一个系列文章,介绍构建 CMS 的不同方面。我会从这里开始,并在此模型的基础上进行扩展,以支持图像上传、用户身份验证以及所有这些好东西。请务必获取我的 RSS 订阅源 或关注我在 Twitter 上!
听起来不错,我一定会关注的。
非常感谢。谢谢!
Jason Lengstorf,感谢!但是您能为这个演示编写删除和编辑方法吗?
再次感谢!
您好,Jason,
关于代码我有些地方不明白。我看到 "var $host",令我感到困惑。我不记得 PHP 有使用 var。我知道 JavaScript 使用 var,但这在这里有什么作用呢?
它是在做些什么吗?一些约定吗?
原来我在使用PHP4 语法.
在 PHP5 中,使用 var 似乎是不必要的。相反,我应该声明变量的可见性(例如 private $host;)。
感谢您指出来!
PHP 太烂了……
Rails 很棒。你可以在 Rails 中用注释在 10 分钟内做到这一点。
RoR FTW!!!
你是个白痴。PHP 是一款很棒的 Web 编程语言 - 到处乱跑告诉别人使用 Rails 而不是 PHP 只会让初学者感到困惑。你不应该用 Rails 来制作一些简单页面的脚本,它也绝不是唯一的选择。而且使用 PHP 绝对没有任何问题 - 看看CakePHP.
谢谢。这很有帮助。我将重新开始使用 PHP,我已经很久没有用过了。
我在服务器上运行您的代码时遇到了错误
注意:未定义索引:admin
指向这一行
echo ( $_GET[‘admin’] == 1 ) ? $obj->display_admin() : $obj->display_public();
我在使用演示(在您的服务器上)时不会出现此错误。
您知道为什么吗?
感谢您撰写这篇文章。我从一些书籍和 w3schools 中完成了对 PHP 和 SQL 的学习。我学到了不少东西,现在我正在网上寻找开发我的第一个网站的方法,您的文章很有帮助,谢谢。
又一个例子,证明那些不知道自己在做什么的人不应该尝试告诉别人如何编写代码。
1: 在 public 中使用 var。var = PHP4 且 public = PHP5 语法
2: 没有遵循任何已建立的编码标准(例如 PEAR 标准)
3: 类基本上用作过程函数的包装器
4: 正如指出的,代码根本没有分离。
5: 使用 if 检查数组索引是否存在会导致警告,应该使用 isset() 代替
6: 在每次请求时构建数据库(如前所述)
由于这不是一篇很高级的文章,代码中大多数新手问题都可以忽略,但至少应该指出来。除非你告诉他们,否则初学者怎么会知道这段代码很糟糕,以及他们应该寻求更多教育呢?
很棒的文章,我喜欢你关于构建第一个 CMS 的初学者教程,但它确实太基础了。它根本没有遵循 MVC 模式,而现在大多数 CMS 都遵循这种模式。你将 HTML 嵌入到 HTML 中,而应该将它们分开。我知道这是为初学者准备的,但你正在把他们带向错误的方向,这更像是为当今的编码 "标准" 而设计的,而不是 10 年前的标准。
非常糟糕的编码风格……你试图让它看起来很专业,但却没有做到。你依赖于一些 PHP 缺陷,忽略了通知,而应该使用所有东西都正确。你甚至没有将设计与代码分离。
我真的不建议任何人使用这段代码。它为成为程序员提供了不好的例子。
很棒的教程。我一直想学习 PHP,优秀的程序员很难找到。:) 会转发到 Twitter 上。
嘿,伙计。不错的教程。
只是提醒一下,"Build the Database" 无法编译,因为 heredoc 结束标识符需要是该行上的第一个也是唯一的元素,但它却被缩进。没什么大不了的,但 php 会触发错误 "Parse error: syntax error, unexpected $end…"。
试试 Ajax: http://www.ajaxbasics.com
嗯,域名失效了?
注意:SimpleCMS\display.php 第 48 行的未定义索引:admin
注意:SimpleCMS\_class\simpleCMS.php 第 30 行的未定义变量:entry_display
如何解决这个问题?
您服务器的通知设置导致了这些错误。要解决第一个问题,您只需要在 **display.php** 中添加一个检查,以查看变量是否已设置
echo ( isset($_GET[‘admin’]) && $_GET[‘admin’] == 1 ) ? …
另一个问题似乎是由于我在开始添加内容之前没有明确地声明 **$entry_display**。要解决这个问题,只需在 **display_public** 函数的开头下方声明 **$entry_display = ”;**。
希望这有帮助!
作为一个 php/mysql 的初学者(经过一年的轻松编码),我仍然不明白为什么 mysql 速度这么慢。
我想在教程中使用简单的代码,整个过程会很快,但一旦你达到了 WordPress 这样的复杂程度,我发现速度并不像我想象的那样快。当然,如果你将你的网站/博客托管在你的 ISP,或者有一个快速的企业内部网服务器,那么我想应该没问题。但在我的 Atom 230/2GB RAM 家庭服务器上不行。
我对这个问题做了很多研究,瓶颈总是 mysql,而不是 php。那么,一个没有数据库的简单 CMS,或者一个使用轻量级数据库的 CMS 呢?不过,这篇文章写得很好,特别是 oophp 部分,我以前没有接触过。–Hans
这远远算不上对 PHP 有用的介绍。这只是一个业余的 PHP 入门教程。
PHP 编程的弊病之一就是 SQL 注入。它们源于使用字符串连接以及经常被遗忘的转义。(作者显然也这样做过。)
如果你想真正了解 PHP 和 MySQL,去寻找一篇关于PDO 或 *SQL 预准备语句* 的文章。它更安全 **并且** 更简单。
在今天这个时代,安全非常重要。任何 "我的第一个 php ___" 教程都需要涵盖这一点,因为糟糕的代码和糟糕的教程已经成为了传统。
你应该使用预准备语句和参数化查询。这使你能够轻松地进行数据验证和清理输入。转义和去除不会涵盖所有情况。本教程让最终用户很容易受到 SQL 注入和 XSS 的攻击。
Mysqli 是一个很好的模块。最好的部分是它内置于 sql 5 及更高版本中。没有理由使用原始查询。
一个非常好的教程。简单明了。我也喜欢你网站的设计。只是好奇,你网站运行的是哪个 CMS?或者你的网站完全是自定义构建的?
WordPress 宝贝。冠军的 CMS =)
虽然我感谢你介绍了这一点,但我对这个教程的主要问题是它没有解释为什么你要做这些事情。例如,我理解 "$this" 明显是一个变量,但为什么我们在数据库调用之前的每个部分都写 "$this->"?这与其说是教程,不如说是 "盲目地复制我的做法,以获得与我完全相同的结果"。我以前用过 PHP,也写过 PHP,所以我对它有基本了解,但我认为,了解事情的 *为什么* 和 *怎么做* 一样重要。
仅代表我个人观点。
很抱歉,但这确实是一个糟糕透顶的 PHP 入门教程,Chris 应该彻底删除这篇文章。这篇文章的作者缺乏经验,有很多坏习惯,并将这些坏习惯传授给毫无戒心的初学者。
它不至于糟糕透顶,因为它不是要成为用 PHP/MySQL 构建 CMS 的百科全书式的介绍,但它也并没有真正传授任何东西。在这方面,我认为它没有对初学者尽到责任。
感谢上帝有 WordPress!
我认为这不是为初学者准备的。有很多东西我不明白,如果你想让这个教程真正适合初学者,你应该解释这些东西。
例如:何时使用 { } 或 [ ] 符号,何时使用 ;
什么是 “$r = 或 $q=,或 $p ” 这些是变量还是 PHP 语言的一部分?
@Jorge,如果你想看更基础的东西,可以查看 http://w3schools.com/php/
问候!
到目前为止,我看到的只是对本教程的抨击;请有经验的程序员发布一些好的资源列表,例如专注于良好的 PHP 编码实践、安全性、如何将代码与 HTML 分离等的教程?
非常感谢!
天哪,人们就是喜欢坐下来批评别人的代码。这是一个不错的,可靠的介绍,讲解了两个流行的技术,别再挑刺了。
话说,我有个问题!我在尝试加载 display.php 时遇到了以下错误。
解析错误:解析错误,预期为
T_STRING' 或
T_VARIABLE’ 或 `T_NUM_STRING’ 在 C:\www\simpleCMS\_class\simpleCMS.php 第 69 行第 69 行是
if ( ($p['title']) )
我已经尝试过 “!empty(…)” 和 “isset(…)” 来确保 $p[‘title’] 是正确的,但相同的错误仍然出现。看起来它需要某种类型声明,对于一个弱类型语言来说这似乎很奇怪。有什么想法吗?
谢谢。
有人提到源代码的 HEREDOC 语句末尾有制表符,这会导致代码中断。检查 display_admin(),确保结束分隔符(“ADMIN_FORM”)前面没有空格。
此外,如果你打算将此代码用于学习之外的任何目的,最好检查一些安全措施,例如 mysqli 或 PDO。SQL 注入是恶意的。你可以在 此处 阅读相关信息。
对于初学者来说,信息非常棒。
我不得不承认,我曾经使用 MySQL 和 PHP,后来我发现了 dreamweaver 函数来创建快速的 CMS,新手。
一旦你开始,就永远不会停止,你可以用一个简单的 GUI 做很多事情。我知道有些人是纯粹主义者,永远不会离开记事本,但对于初学者来说,这是一个很好的起点。
这代码是多么糟糕的垃圾!失败!
我已经学到了足够的 PHP 和 MySQL 来应付日常工作。期待本系列的其余部分,尤其是显示、编辑和保存更改部分。
对于初学者来说,信息非常棒。
这绝对不适合初学者……
非常感谢这个很棒的教程,期待更多!
我个人担心你的 CMS 是根据 GET 变量设置为 1 来显示管理表单的。至少你应该建议使用管理员设置的键值(密码)来代替。
感谢这个易于理解的 PHP/MySql 教程 :)
这很棒,很有帮助。
继续努力。
Jason Lengstorf,感谢!但是您能为这个演示编写删除和编辑方法吗?
再次感谢!
这是一篇非常有用的文章,写作和呈现都很好。你认为对于一些 PHP MySQL 新用户来说,在如此早期使用类和函数是不是太多了?
各位,CMS 是一个很好的概念。谢谢。如果你要谈论数据库,请咨询 DBA 或数据库专家。你对数据库和表感到困惑。使用 MySQL,你可以拥有多个数据库。数据库用于对相关表进行分组。表不是数据库。数据库不是表。希望这有帮助。
感谢上帝,编写主要框架的人并没有仅仅依赖现有的框架。仅仅使用其他所有人已经做过的事情并不是获得更好的新东西的好方法。在现有的代码基础上不断改进是一回事,但偶尔从头开始是使用所有最新技术的最佳解决方案,这也是你学习的方式。
感谢这个教程。
对于所有发布负面评论的人来说。消极很容易,但你们自己实际上写不出更好的代码,因为如果你能,那你就可以创建自己的框架并告诉我们。
感谢这个教程!
我和我的一个朋友一直在使用 CMS 开发网站,虽然他懂 PHP,但我却不懂。这对我理解数据库连接以及如何使用 PHP 添加/显示数据库内容非常有帮助。
再次感谢,
Chris
我认为这个教程很好地展示了使用简单的 PHP 和 MySQL 可以构建什么。
讽刺的是,这么多人都在指责它很糟糕,却没有推荐任何替代的教程。:/ 如果你想批评它,为什么不至少提供一个替代方案呢?
很棒,谢谢。
谢谢,它帮助我学习基于 CMS 的项目……。
我真的很喜欢这个,期待阅读更多,也许编辑并加入一些 ajax,例如包含所有内容的小教程。
太棒了!感谢 Jason!
我可以翻译这个教程吗?
太棒了……。
谢谢兄弟。
我真的不明白为什么有人想要自己构建 CMS,而不是直接扩展 Drupal 或其他现有的东西。
抱歉要加入负面评论,但我认为如果你要教如何编写基本的 CMS,那么还需要提到一些东西。(我不会提之前已经提过的一些东西。)
OOP - 你提到使用 OOP 是一个好习惯,但在你的示例中你并没有有效地使用 OOP,也没有正确地教它。当用户开始学习关于 OOP 的进一步实践并尝试在你的示例中使用它时,他们会感到沮丧,因为它不起作用。你有一个超级类,它组合了大量的函数。你不能像这样扩展此类。
SELECT * FROM… 很慢,而且是一种不好的做法。从一开始就让新用户使用正确的做法!当你的应用程序变得更大时,你的 MySQL 查询会花费更长时间,因为 MySQL 必须搜索整个表才能获得你需要的 1(或 2)个东西。试试
为什么你使用 HEREDOC 而不是回显字符串或跳出 PHP?
应该始终使用花括号。在 Google 上搜索“PHP 编码规范”,或者我推荐来自 Evolt.org 的这篇文档。
我的评论在网络空间中丢失了,所以我会重新创建它(很快)。
关于这篇文章,我不会提到之前的评论,但
– OOP。更简洁的代码和良好的实践 - 如果做对了。如果你要展示一种技术,请正确地使用它。如果这些用户中任何一个深入学习 OOP,那么他们会很失望地发现他们无法完全利用你教他们的东西。
– SQL。SELECT * FROM.. 当你的应用程序变得更大时,会变慢,而且是一种不好的做法。请使用 SELECT this, that FROM.. 而不是它,你不想进行全表搜索。
为什么所有内容都在 PHP 中,为什么不是 ASP.NET?我认为 ASP.NET 比 PHP 好得多,我现在不想再学习一门新的语言。请也提供一些 ASP.NET 的经验。
很棒的文章。 很高兴我偶然发现了你的网站。感谢分享这个有用的网站。点赞!
您好,先生,
这确实是一个超级 php 类考试! 我过去几天一直在寻找这个,终于找到了!
非常感谢!
这篇文章不错。
对于试图学习如何做事情的初学者来说,安全不是一个相关的话题。 让我们现实一点,你真的认为一个新手会偶然发现这个教程来开发一个网上银行平台吗?(实际上,这不会让我感到震惊,但我怀疑这不是作者的目标)。
一个新手更有可能用这个建立一个小的“Hello World”网站或展示他孩子的照片。 所以它对 SQL 注入是开放的,当然…… 但是当新手发现 PedoBear 被叠加到他孩子的照片中时,他将磨练他的安全技能。
任何严肃的开发人员都会参加更强大的专业开发课程,然后偶尔进行安全刷新。 每个人都知道这一点。
现在…… 任何使用开源技术的人都不应该敢于因为自由分享知识而抨击其他人。 永远。 出于对读者的尊重,纠正错误,但不要抨击作者。 他只是想为社区做出贡献。 这就是开源的意义所在。
我喜欢你这样发放的方式。
非常感谢..
这个世界需要像你这样的人。干得好
你的 buildDB(); 是在创建表而不是数据库,对吧? 你的变量表实际上是一个数据库?
很棒的教程。 面向对象的方法绝对是未来的发展方向。 我将在我的第一个大型 php 项目中使用这种技术。
不错的教程。 我要实现 CLASS 技术来放置我的 PHP 代码,因为它让我的 HTML 代码很乱,看到很多 PHP 插入……lol…… 但是这篇文章可能是 3-4 年前的…… 我注意到它使用了旧的 MySQL_*…… 在你的 SQL 代码中使用它是不安全的,对于更高版本的 PHP 来说是过时的,就像有人告诉我的那样…… 我建议使用 MySQLi_* 或 PDO…… (在 W3Schools.com 上了解更多关于 MySQLi_* 实现的信息)…… 这种方法与旧的相比,安全性更高…… 因为它不再维护…… 我刚刚更新为使用新的…… 所以我在这里期待更多 PHP 技术,主要是关于 SQL 注入,因为这对像我这样的不依赖框架的开发人员来说是一个非常大的问题…… 网站不错…… 我要把它加到书签里……
请不要遵循本教程,并找到一个更新的教程。
请注意,本教程非常旧,使用了过时的方法(例如 mysql_* 函数 - 你需要使用 mysqli_* 或 PDO 代替)。
如果这个网站从他们的网站上完全删除了这个教程,他们将对互联网有所帮助。
这对初学者来说是一个很棒的教程…… 我开始学习 php,这是我的第一个教程。
谢谢,伙计。
您好,教程不错,但是您应该更新代码,因为有些代码已过时。 这是一个很棒的网站,在谷歌索引中排名很高,所以它会让很多尝试使用代码的新手感到困惑。