26

在 ASPNET 中,我开始喜欢应用程序和缓存存储。他们太棒了。对于没有经验的人,您可以将数据逻辑对象放入其中,嘿-presto,您只需查询数据库一次即可获取一些数据。

迄今为止最好的 ASPNET 功能之一,IMO。

我已经放弃了 Linux 的 Windows,因此放弃了 webdev 的 PHP、Python 和 Ruby。我最常使用 PHP,因为我开发了几个开源项目,都使用 PHP。

不用说,我已经探索了 PHP 在缓存数据对象方面必须提供的功能。到目前为止,我玩过:

  1. 序列化到文件(一个非常缓慢/昂贵的过程)
  2. 将数据作为 JSON/XML/plaintext/etc 写入文件(读取操作更慢)
  3. 将数据作为纯 PHP 写入文件(读取速度最快,但写入操作相当复杂)

我现在应该强调的是,我正在寻找一种不依赖第三方应用程序(例如 memcached)的解决方案,因为这些应用程序安装在各种场景中,其中大多数没有安装权限(例如:a便宜的共享主机帐户)。

所以回到我现在正在做的事情,坚持文件安全吗? Rule 1在生产服务器安全性一直禁用文件写入,但我真的看不到任何方式 PHP可以缓存,如果它不能写。是否有任何提示和/或技巧来提高安全性?

还有另一种我忘记的持久化文件方法吗?

在“有限”环境中是否有更好的缓存方法?

4

8 回答 8

18

序列化是相当安全且常用的。但是,还有另一种选择,那就是缓存到内存。查看memcachedAPC,它们都是免费且高性能的。这篇关于 PHP 中不同缓存技术的文章可能也很有趣。

于 2008-09-24T13:00:03.470 回答
7

回复:还有另一种我忘记的持久化文件方法吗?

它的实用性有限,但如果您有一个特别强大的数据库查询,您可以将序列化对象写回索引数据库表。您仍然会有数据库查询的开销,但它会是一个简单的选择,而不是强大的查询。

回复:坚持到文件安全吗?和便宜的共享主机帐户)

可悲的事实是廉价的共享主机并不安全。您对有权访问您服务器的 100,500 或 1000 名其他人的信任程度如何?出于历史和(具有讽刺意味的)安全原因,共享托管环境让 PHP/Apache 作为非特权用户运行(PHP 作为 Apache 模块运行)。这里的安全理由是,如果面向世界的 apache 进程受到威胁,则利用者只能访问无法处理重要系统文件的非特权帐户。

不好的部分是,这意味着每当您使用 PHP 写入文件时,该文件的所有者都是同一个非特权 Apache 用户。对于系统上的每个用户都是如此,这意味着任何人都可以读取和写入文件。上述场景中的理论黑客也可以访问这些文件。

PHP 中还有一个长期的不良做法,即为目录和文件授予 777 的目录权限,以使非特权 apache 用户能够写出文件,然后将目录或文件保持在该状态。这使系统上的任何人都具有读/写访问权限。

最后,你可能认为默默无闻可以拯救你。“他们不可能知道我的秘密缓存文件在哪里”,但你错了。共享主机将用户设置在同一个组中,大多数默认文件掩码将授予您的组用户对您创建的文件的读取权限。有时通过 SSH 连接到您的共享主机帐户,向上导航一个目录,您通常可以开始浏览系统上的其他用户文件。这可以用来嗅出可写文件。

解决方案并不漂亮。一些主机会提供 CGI Wrapper,让您可以将 PHP 作为 CGI 运行。这里的好处是 PHP 将作为脚本的所有者运行,这意味着它将作为您而不是非特权用户运行。避免了问题!新问题!传统的 CGI 在二月份就像糖蜜一样缓慢。

有 FastCGI,但 FastCGI 很挑剔,需要不断调整。没有多少共享主机提供它。如果你找到了,那么他们很可能会启用 APC,甚至可能会为 memcached 提供一种机制。

于 2008-09-24T13:37:05.377 回答
4

我有一个类似的问题,因此写了一个解决方案,一个用 PHP 编写的内存缓存。它只需要 PHP 构建来支持套接字。除此之外,它是一个纯 php 解决方案,应该在共享主机上运行良好。

http://code.google.com/p/php-object-cache/

于 2009-07-01T07:12:57.827 回答
3

如果我必须能够写,我总是做的是确保我不会在任何有 PHP 代码的地方写。通常我的目录结构看起来像这样(它在项目之间有所不同,但这是一般的想法):

project/
  app/
  html/
    index.php
    data/
  cache/

appWeb 服务器不可写(最好是 index.php)。 cache是可写的,用于缓存解析的模板和对象等内容。data可能是可写的,这取决于需要。也就是说,如果用户上传数据,它就会进入数据。

指向 Web 服务器,project/html并使用任何方便的方法设置index.php为脚本,以便为项目中的每个页面运行。您可以在 Apache 中使用 mod_rewrite,或者内容协商(我的偏好,但通常不可能),或者您喜欢的任何其他方法。

您所有的真实代码都存在于 中app,Web 服务器无法直接访问该代码,但应将其添加到 PHP 路径中。

这对我的几个项目来说效果很好。例如,我什至能够让维基媒体使用这种结构的修改版本。

哦...我会使用 serialize()/unserialize() 来进行缓存,尽管生成 PHP 代码具有一定的吸引力。我所知道的所有模板引擎都会生成要执行的 PHP 代码,从而使后解析非常快。

于 2008-09-24T13:24:22.553 回答
1

如果您有权访问数据库查询缓存(即 MySQL),您可以序列化您的对象并将它们存储在数据库中。数据库将负责将查询结果保存在内存中,这样应该会非常快。

于 2008-09-24T13:14:13.343 回答
1

您没有说明-为什么-您要尝试缓存对象。您是在尝试加速缓慢的数据库查询、解决昂贵的对象实例化、避免重复生成复杂页面、维护应用程序状态,还是只是在漫长的冬天强制存储对象?

鉴于大多数低成本共享主机的严重限制,最佳解决方案将取决于您要完成的工作。寻求最低限度的共享托管意味着您必须接受您不会使用最好的工具。这些数字很难量化,但在托管成本、网站性能和开发人员时间(即快速、便宜或容易)之间存在权衡。

于 2008-12-05T04:16:19.520 回答
0

理论上可以在会话中存储对象。这可能会让您摆脱文件写入禁用问题。此外,您可以将会话存储在 mysql 内存支持的表中以加快查询速度。

于 2008-09-24T12:55:01.783 回答
0

某些托管位置可能已编译 APC。这将允许您将对象存储在内存中。

于 2008-09-24T13:02:37.350 回答