我正在制作一个网站,允许用户共享带有缩略图的可搜索相册,这些相册将受密码保护。我的计划是验证密码并将 PHP session 设置为等于相册的 ID。然后当用户加载相册时,服务器将提供所有图片引用 ID 的列表。然后,使用 ajax 调用,客户端将通过 GET 请求(包括照片 ID)请求所有符合请求条件的图片。然后我将使用 PHP 检查当前 session 是否已获得该相册的授权,然后对图片位置进行 MySQL 查询,然后返回图片。
既然您已经阅读了我的设计思路,我担心如果相册足够大,服务器负载会迅速增加,因为每个缩略图都需要单独的请求和 MySQL 查询。我还没有实现和测试,但想知道我是否应该重新开始我的设计。
有没有更好的方法来解决这个问题?
一个简单的 PHP 脚本和 MySQL 查询的负载是否会很大?
最佳答案
没有理由要求每个单独的缩略图都需要单独的请求甚至单独的查询。您可以在单个请求和单个查询中同时执行这两项操作。
假设您的缩略图作为 URL 存储在您的数据库中并与相册 ID 相关联。这意味着像这样的单个查询可以检索相册的所有缩略图。
SELECT
thumbnails.url
FROM
thumbnails
JOIN
albums ON thumbnails.album_id = albums.id
WHERE
thumbnails.album_id = 1
现在您可以简单地对这些结果进行分页以减少服务器负载。假设您希望每页最多加载 50 个缩略图。
SELECT
thumbnails.url
FROM
thumbnails
JOIN
albums ON thumbnails.album_id = albums.id
WHERE
thumbnails.album_id = 1
LIMIT
0,50
然后对于下一页,您可以执行 LIMIT 50,50
和下一页 LIMIT 100,50
等等。
您可以在 AJAX 响应中将缩略图结果列表作为 JSON 发送回客户端,客户端可以通过 javascript 将每个缩略图加载到页面上。
为什么你可能认为这行不通
如果您的想法是您需要对这些缩略图进行单独请求,因为您希望 PHP 验证用户是否有权查看相册,那么您就太过努力地同时解决两个问题了。
将缩略图 URL 获取到客户端的问题是第一步。这很容易通过检查用户的 $_SESSION
来实现,就像您计划做的那样,并确保在您进行查询之前他们可以访问 album_id
并将他们发回JSON 结果。
下一步是限制对相册及其缩略图的访问。不幸的是,您必须在 HTTP/1.1 中为此单独请求。没有办法解决这个问题,但是这仍然不需要很昂贵。
您只需使用 PHP 来验证 $_SESSION
变量是否包含所需的 album_id
检查并依赖您的网络服务器的 Sendfile capabilities处理向客户提供实际图像。
因此 PHP 只处理验证用户是否有权查看图像的部分。您的网络服务器会处理提供服务的部分。此请求中没有要执行的数据库查询。所以这不是数据库负载问题。
在 PHP 中,使用 Apache httpd(作为示例),这会像这样工作。
if (isset($_SESSION['album_id']) && $_SESSION['album_id'] === $_GET['album_id']) {
// User has access
header("X-Sendfile: " . $pathToImageOnFileSystem);
exit;
} else {
// User is not authorized :/
echo "Unauthorized access!";
}
这样做是将响应 header 发送回您的网络服务器,让它知道“您需要将 $pathToImageOnFileSystem
中指定的文件提供给客户端”。在将该 header 发送回您的 Web 服务器后,PHP 的角色结束。网络服务器然后完成其余的工作。所以 PHP 没有被束缚。
棘手的部分是确保以一种将 URL 指向图像 ID 的方式定义网络服务器重写规则,您可以在其中将其映射到文件系统上的文件。例如,您可以将图像存储在 /home/myapp/images/{album_id}/{image_id}
中,以便像 http://www.example.com/images/1/1 这样的 URL由您的 Web 服务器读取并发送到 PHP,然后 PHP 可以确定 $pathToImageOnFileSystem
应该是 /home/myapp/images/1/1
。 PHP 通过检查 $_SESSION
中的 albumb_id 已经知道用户是否具有访问权限,因为它会在之前的身份验证中存储。
当然,还需要确保文件在由您的网络服务器提供时发回正确的 MIME 类型和文件扩展名。因此,您可能希望将 /home/myapp/images/{album_id}/{image_id}
映射到 /home/myapp/images/{album_id}/{image_id}.*
或类似的内容。
关于php - 受密码保护的相册 PHP/MySQL 服务器负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39382367/