将PHP对象缓存到文件的方法?
在ASPNET中,我开始喜欢应用程序和缓存存储。他们很棒。对于未启动的用户,我们只需将数据逻辑对象放入其中,嘿,我们只需查询一次数据库即可获得少量数据。
到目前为止,最好的ASPNET功能之一是IMO。
从那以后,我放弃了Windows的Linux,因此放弃了PHP,Python和Ruby的webdev。我使用PHP最多的原因是因为我开发了几个开源项目,全部使用PHP。
不用说,我已经探讨了PHP在缓存数据对象方面必须提供的功能。到目前为止,我玩过:
- 序列化到文件(相当慢/昂贵的过程)
- 将数据以JSON / XML / plaintext / etc格式写入文件(对于读取操作而言甚至更慢)
- 将数据作为纯PHP写入文件(最快的读取速度,但是写操作相当复杂)
我现在要强调的是,我正在寻找不依赖第三方应用程序(例如memcached)的解决方案,因为这些应用程序安装在各种情况下,其中大多数没有安装权限(例如:廉价的共享托管帐户)。
回到我现在正在做的事情,是否坚持文件安全性?生产服务器安全性中的"规则1"一直是禁用文件写入功能,但是我真的看不到PHP无法编写任何方式可以缓存的方法。是否有任何提示和/或者技巧来增强安全性?
还有我遗忘的另一个"持久保存到文件"方法吗?
在"有限的"环境中,有没有更好的缓存方法?
解决方案
从理论上讲,可以在会话中存储对象。这可能使我们摆脱文件写入禁用问题。另外,我们可以将会话存储在mysql内存支持的表中,以加快查询速度。
序列化是相当安全的,并且经常使用。但是,还有另一种方法,那就是缓存到内存。看看memcached和APC,它们都是免费的,并且性能很高。这篇有关PHP中不同缓存技术的文章也可能会引起兴趣。
某些托管场所可能已编译了APC。这将允许我们将对象存储在内存中。
如果我们有权访问数据库查询缓存(即MySQL),则可以序列化对象并将其存储在数据库中。数据库将负责将查询结果保存在内存中,因此应该很快。
如果必须写,我通常会做的是确保没有在任何有PHP代码的地方写东西。通常,我的目录结构看起来像这样(在项目之间有所不同,但这是基本思路):
project/ app/ html/ index.php data/ cache/
Web服务器无法写入" app"(最好也不是index.php)。 " cache"是可写的,用于缓存诸如已解析的模板和对象之类的内容。根据需要,"数据"可能是可写的。也就是说,如果用户上传数据,它将进入数据。
网络服务器指向" project / html",并且使用任何方便的方法将" index.php"设置为在项目中每个页面上运行的脚本。我们可以在Apache中使用mod_rewrite,也可以使用内容协商(我的偏爱,但通常是不可能的)或者任何其他我们喜欢的方法。
我们所有的真实代码都存在于" app"中,Web服务器无法直接访问它,但应将其添加到PHP路径中。
对于我来说,这在几个项目中都非常有效。例如,我什至可以使用Wikimedia来处理此结构的修改版本。
哦。。。虽然生成PHP代码有一定吸引力,但我会使用serialize()/ unserialize()进行缓存。我所知道的所有模板引擎都会生成要执行的PHP代码,从而使后解析非常快。
回复:还有我遗忘的另一个"持久保存到文件"方法吗?
它的用途有限,但是如果我们有一个特别强大的数据库查询,则可以将序列化的对象写回到索引数据库表中。我们仍然会有数据库查询的开销,但是与功能强大的查询相反,这是一个简单的选择。
回复:坚持文件安全吗?和廉价的共享托管帐户)
可悲的事实是廉价的共享主机并不安全。我们对100,500或者1000个可以访问服务器的其他人信任多少?出于历史和(具有讽刺意味的)安全性原因,共享托管环境将PHP / Apache作为非特权用户运行(PHP作为Apache模块运行)。这里的安全性合理性是,如果面对全球的apache进程受到威胁,则开发者只能访问一个没有特权的帐户,而该帐户无法破坏重要的系统文件。
糟糕的是,这意味着每当我们使用PHP写入文件时,该文件的所有者就是同一非特权Apache用户。对于系统上的每个用户都是如此,这意味着任何人都可以读写文件。在上述情况下,理论上的黑客也可以访问这些文件。
PHP中还存在一种持续的不良习惯,即对目录和文件授予777的目录权限,以使无特权的apache用户可以写出文件,然后将目录或者文件保持该状态。这样,系统上的任何人都可以进行读/写访问。
最后,我们可能认为默默无闻可以挽救我们。 "他们无法知道我的秘密缓存文件在哪里",但是你会错的。共享主机在同一组中设置用户,大多数默认文件掩码将使组用户对我们创建的文件具有读取权限。有时通过SSH进入共享的托管帐户,浏览目录,通常可以开始浏览系统上的其他用户文件。这可以用来嗅出可写文件。
解决方案不是很好。一些主机将提供一个CGI包装器,使我们可以将PHP作为CGI运行。这样做的好处是PHP将以脚本的所有者身份运行,这意味着它将以身份而不是非特权用户身份运行。问题避免了!新问题!传统的CGI在2月份像糖蜜一样缓慢。
有FastCGI,但是FastCGI很挑剔,需要不断调整。没有很多共享主机提供它。如果我们发现这样做的话,很可能他们将启用APC,甚至可能能够提供一种用于memcached的机制。
我们无需说明-为什么要缓存对象。我们是要加快数据库查询速度,解决昂贵的对象实例化,避免重复生成复杂页面,保持应用程序状态,还是只是为了在漫长的冬季强迫性地存储掉对象?
考虑到大多数低成本共享主机的严重限制,最好的解决方案将取决于我们要实现的目标。精打细算的共享主机意味着我们必须接受自己不会使用最好的工具。这些数字很难量化,但是在托管成本,站点性能和开发人员时间(即快速,便宜或者容易)之间需要权衡取舍。
我遇到了类似的问题,因此写了一个解决方案,一个用PHP编写的内存缓存。它只需要PHP构建即可支持套接字。除此之外,它是一个纯PHP解决方案,应该可以在共享主机上正常运行。
http://code.google.com/p/php-object-cache/