2

我使用 php GET 检查 URL 中的 ID,然后从与该 ID 匹配的数据库中检索 tekst。这是执行此操作的代码片段:

function getLyric() {
$id = (int)$_GET['id'];
$query = mysql_query("SELECT * FROM lyrics WHERE id = ".$id."") or die(mysql_error());
if ($row = mysql_fetch_assoc($query)) { ?>
    <h1><?= $row['title']; ?> lyrics</h1>
    <h2><?= $row['author']; ?></h2>

    <pre><?= $row['lyrics']; ?></pre>
    <?php }
else { header("HTTP/1.1 404 Not Found"); header("Status 404 Not Found"); }
}

这就是我调用此函数的页面的外观:

<?php include 'includes/header.php' ?>
<?php getLyric(); ?>
<?php include 'includes/footer.php' ?>

不幸的是,函数中的 404 部分不起作用。我收到以下警告。Warning: Cannot modify header information - headers already sent by [redacted] functions.php on line 61. 第61行是404部分;“其他{标题}〜”。

我从 Stackoverflow 了解到这是因为该<html><head>部分已经在页面上输出,所以我不能再更改它了。这是对的?

以前当我没有 else~ 部分时,我只是得到一个空白页。在这种情况下如何正确发送 404?如果我不能,最接近的选择是什么?

4

7 回答 7

6

您只需要将逻辑与演示文稿分开:

function getLyric() {
    $id = (int)$_GET['id'];
    $query = mysql_query("SELECT * FROM lyrics WHERE id = ".$id."") 
                 or die(mysql_error());
    return mysql_fetch_assoc($query);
}

...然后:

<?php
$row = getLyric();

if (!$row) {
    header("HTTP/1.1 404 Not Found");
    exit;
}

include 'includes/header.php' 
?>

<h1><?= $row['title']; ?> lyrics</h1>
<h2><?= $row['author']; ?></h2>

<pre><?= $row['lyrics']; ?></pre>

<?php 
include 'includes/footer.php'
?>
于 2012-04-23T20:06:32.533 回答
2

一旦您发送了 HTML 代码,您就无法更改标题。标头告诉浏览器如何处理请求的页面。如果它已经收到 HTML,它会假定 content-type:text\html 并开始渲染页面。那时您的标题已定义,您无法返回。

于 2012-04-23T20:01:31.453 回答
2

不,你不能,标题是第一个出去的东西,所以一旦你发回文本,标题已经可以这么说。

您可能希望在包含标题之前运行查询,运行检查以确保返回数据,然后打印。

function getLyric() {
  $id = (int)$_GET['id'];
  $query = mysql_query("SELECT * FROM lyrics WHERE id = ".$id."") or die(mysql_error());
  if ($row = mysql_fetch_assoc($query)) {
    include 'includes/header.php'; 
  ?>
      <h1><?= $row['title']; ?> lyrics</h1>
      <h2><?= $row['author']; ?></h2>

      <pre><?= $row['lyrics']; ?></pre>
      <?php }
  else { header("HTTP/1.1 404 Not Found"); }
}

<?php getLyric(); ?>
<?php include 'includes/footer.php' ?>
于 2012-04-23T20:01:58.443 回答
0

您可以在脚本中启用输出缓冲。

例子:

<?php
ob_start();
echo 'Hi';
header('Location: http://someurl');
exit;
?>

请在使用前确定输出缓冲是什么。

于 2012-04-23T20:06:00.663 回答
0
ob_start();
header("location:somepage.php");
ob_end_flush();

实际上,如果您打开了输出缓冲,则在刷新之前不会发送任何内容。甚至没有标题。

于 2012-04-23T20:08:10.380 回答
0

如您所见,当内容已发送时,无法发送 404。你有两个选择,IMO

  • 修改您的代码以启用输出缓冲。这实质上意味着您回显的所有内容或 PHP 标记之外的内容都会进入缓冲区并且不会发送到客户端。在这里阅读

  • 修改函数以给出数据而不是 UI。这意味着函数 getLyrics() 应该给出相关行。在您使用include任何标题之前,请务必检查该功能是否表明该记录存在。否则,您始终可以发送 404。这实际上是推荐的,并且是一个很好的设计,因为它本质上将逻辑与 UI 分离。

于 2012-04-23T20:08:57.217 回答
0

一旦发送了标题,您将无法再发送它们。您可以做的是启用输出缓冲,它基本上会等到脚本执行完毕后再输出内容。这将允许您在脚本中的任何位置设置标题,但根据您的脚本会产生一些轻微的后果,您应该在盲目启用它之前阅读它。

另外,请阅读 SQL 注入。您的网站极易被利用。

于 2012-04-23T20:03:58.157 回答