我正在编写一个关于 PHP+MySQL 的 CMS。我希望它可以自我更新(在管理面板中单击一次)。最佳实践是什么?
如何比较当前版本的 cms 和更新版本(应用程序本身和数据库)。它应该只下载 zip 存档、upzip 并覆盖文件吗?(但如何处理不再使用的文件)。如何检查更新是否正确下载?它还支持模块,我希望这些模块可以从 cms 的管理面板下载。
我应该如何更新 MySQL 表?
6 回答
- 将您的代码与配置文件和其他变量文件(上传的图像、缓存文件等)放在一个单独的位置
- 将模块与主代码分开。
- 确保您的代码具有更改自身的文件系统权限(例如使用 SuPHP)。
如果您这样做,最简单的方法是完全下载新版本(无增量补丁),并将其解压缩到与包含当前版本的目录相邻的目录中。由于代码目录中不会有变量文件,您可以删除或重命名旧文件并重命名新文件以替换它。
您可以将版本号保留在代码中的全局常量中。
至于 MySQL,除了为每个更改数据库布局的版本制作升级脚本之外别无他法。即使是更改表定义的自动解决方案也不知道如何更新现有数据。
一个更具实验性的解决方案可能是使用phpsvnclient库之类的东西。
具有以下特点:
- 列出给定 SVN 存储库目录中的所有文件
- 检索文件的给定修订版
- 检索在存储库或两个修订之间的给定文件中所做的更改日志
- 获取存储库最新版本
通过这种方式,您可以查看是否有新文件、已删除文件或更新文件,并且仅在本地应用程序中更改这些文件。
我认为这将有点难以实施,但好处可能是更容易和更快地向您的 CMS 添加更新。
您有两种情况需要处理:
- Web 服务器可以写入文件。
- Web 服务器无法写入文件。
这只是说明您是解压缩 ZIP 文件还是使用 FTP 更新文件。在以太情况下,您的第一步是转储数据库并备份现有文件,以便在出现严重错误时用户可以回滚。正如其他人所说,将用户可能自定义的任何内容保留在更新范围之外很重要。Wordpress 很好地做到了这一点。如果用户对核心逻辑代码进行了更改,他们可能足够聪明,可以自行解决任何合并冲突(并且足够聪明,知道一键升级可能会丢失他们的修改)。
您的第二步是确保您的脚本在浏览器关闭时不会死机。这是一个真正不应该中断的过程。您可以通过ignore_user_abort(true);
或其他方式完成此操作。或者,如果您愿意,允许用户选中一个框,上面写着“即使我断开连接也要继续”。我假设您将在内部处理错误。
现在,根据权限,您可以:
- 将要更新的文件压缩到系统/tmp目录下
- 将要更新的文件压缩为主目录下的临时文件
然后你准备好:
- 下载并解压更新
en situ
,或到位。 - 下载更新并解压到系统的/tmp目录下,使用FTP更新web根目录下的文件
然后您可以:
- 根据需要应用任何 SQL 更改
- 询问用户是否一切正常
- 如果事情变得糟糕就回滚
- 清理系统 /tmp 目录中的临时目录,或用户的 Web 根目录 / 主目录中的任何暂存文件。
最重要的方面是确保在出现问题时可以回滚更改。要确保的另一件事是,如果您使用 /tmp,请务必检查暂存区的权限。0600
应该做得很好。
看看 Wordpress 和其他人是如何做到的。如果您选择的许可证和他们的同意,您甚至可以重新使用其中的一些代码。
祝你的项目好运。
有一个名为 SQLOO(我创建的)的 SQL 库试图解决这个问题。它仍然有点粗糙,但基本思想是您在 PHP 代码中设置 SQL 模式,然后 SQLOO 更改当前数据库模式以匹配代码。这允许 SQL 模式和附加的 PHP 代码以更小的块一起更改。
http://code.google.com/p/sqloo/
http://code.google.com/p/sqloo/source/browse/#svn/trunk/example <-示例
根据对许多应用程序、CMS 等的经验,这是一种常见的模式:
- 升级通常是单向的。可以拍摄完整系统状态的快照以在发生故障时进行恢复,但恢复通常需要丢失自升级以来添加到系统的所有数据/内容/日志。如果某些内容未正确转换(例如数据库表更改、内容转换、外键约束、索引创建等),执行增量回滚可能会使数据面临风险。如果您进行了回滚脚本无法进行的自定义,则尤其如此可能占。
- 升级文件包含一些身份验证/验证手段,例如 md5 或 sha1 哈希和/或数字签名,以确保它来自受信任的来源并且未被篡改。这对于自动升级过程尤为重要。假设黑客利用了一个漏洞并告诉它从恶意来源升级。
- 升级期间应用程序应处于脱机模式。
- 应用程序应在升级后执行自检。
我同意Bart van Heukelom的回答,这是最常见的做法。
唯一的其他选择是将您的 CMS 变成一堆远程 Web 服务/脚本和外部 CSS/JS 文件,您只在一个位置托管。
然后,使用您的 CMS 的每个人都将连接到您的中央“CMS 服务器”,而他们(调用)服务器上的所有内容都是一组脚本,用于调用您的 Web 服务/脚本,这些脚本执行所有处理和输出。如果您沿着这条路线走,则需要识别/验证每个请求,以便为给定的 CMS 用户返回相应的数据。