【问题标题】:Trying to embed Youtube Video using URL link with PHP & Prepared Statement尝试使用带有 PHP 和 Prepared Statement 的 URL 链接嵌入 Youtube 视频
【发布时间】:2018-10-26 09:06:33
【问题描述】:

我使用以下方法在我的页面上嵌入 Youtube 视频:

$body = strip_tags($body); //removes html tags 
// $body = mysqli_real_escape_string($this->con, $body);
$check_empty = preg_replace('/\s+/', '', $body); //Deletes all spaces 

if($check_empty != "") {

    $body_array = preg_split("/\s+/", $body);

    foreach ($body_array as $key => $value) {

        if(strpos($value, "www.youtube.com/watch?v=") !== false) {

            $link = preg_split("!&!", $value);
            $value = preg_replace("!watch\?v=!", "embed/", $link[0]);
            $value = "<br><iframe frameborder=\'0\' style=\'visibility:visible; border: 1px solid #fff;\' width=\'590\' height=\'315\' src=\'" . $value ."\'></iframe>";
            $body_array[$key] = $value;
        }
    }

    $body = implode(" ", $body_array);

这是我用来输入数据库的:

$query = mysqli_query($this->con, "INSERT INTO posts VALUES('', '$body', '$added_by', '$user_to', '$date_added', 'no', 'no', '0', '$imageName')");
$returned_id = mysqli_insert_id($this->con);

当我将查询更改为这样的准备语句时:

$no = 'no';
$zero = 0;
$empty = '';

$query = $this->con->stmt_init();
$query->prepare("INSERT INTO posts VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
$query->bind_param('issssssis', $empty, $body, $added_by, $user_to, $date_added, $no, $no, $zero, $imageName);
$query->execute();
$returned_id = mysqli_insert_id($this->con);
$query->close();

我的 Youtube 链接不再有效。使用常规语句,他们像这样输入 dB:

<br><iframe width='420' height='315' src='https://www.youtube.com/embed/0EqINqnEa-Y'></iframe><br>

使用准备好的语句,我在 dB 中得到了这个,然后页面上显然出现了错误。

<br><iframe frameborder=\'0\' style=\'visibility:visible; border: 1px solid #fff;\' width=\'590\' height=\'315\' src=\'https://www.youtube.com/embed/f_WqYtj1Wik\'></iframe>

关于如何纠正这个问题的任何想法?

【问题讨论】:

  • 我意识到了,但是这些不需要转义吗?这个想法是让 $body 值安全地进入数据库。
  • 他们不应该从一开始就被转义 - 而不是在那个地方。应该使用 适当的 函数处理数据,以使其安全地插入 SQL 查询 - 本来应该是 mysqli_real_escape_string。但是使用正确使用占位符然后将值绑定到之后的准备好的语句,转义数据的步骤不再需要 - 因为语句语法和数据在第一次没有混合在一起地点。
  • 你可以看到在前面的查询中我使用了mysqli_real_escape_string,但是当我切换到准备好的语句时我把它注释掉了。但是单独的mysqli_real_escape_string 没有处理插入的数据显示什么。它需要转义才能显示。
  • 但是在准备好的时候是的,没有必要也没有'mysqli_real_escape_string
  • @Raylene 我可以建议您不要在数据库中存储大量 HTML 吗?它不仅会用大部分冗余数据填充您的数据库表,而且如果您只保存视频 id 字符串,那么您将来可以非常简单地管理数据的显示(以防您想调整 &lt;iframe&gt; 或其他东西的大小。如果您显示您的原始输入,我想看看我是否可以向您展示一种更直接的方法来提取视频 ID 并优化您的代码。

标签: php mysqli youtube prepared-statement


【解决方案1】:

如果您更新您的问题以显示您的原始输入数据,我会尝试为您提供一种更简洁的方式来提取 youtube 网址。在那之前,这是我推荐的从一个独立的 url 字符串开始的代码:

$url = "www.youtube.com/watch?v=0EqINqnEa-Y";
$query = parse_url($url, PHP_URL_QUERY);
parse_str($query, $array);
$video = $array['v'];

if (!$stmt = $this->con->prepare("INSERT INTO posts VALUES (NULL, ?, ?, ?, NOW(), 'no', 'no', 0, ?)")) {  // NULL for AUTOINCREMENT
    echo "Stmt Preparation Error"; // $this->con->error
} elseif (!$stmt->bind_param('ssss', $video, $added_by, $user_to, $imageName)) {  // store video id, not html
    echo "Param Binding Error"; // $stmt->error
} elseif (!$stmt->execute()) {
    echo "Stmt Execution Error"; // $stmt->error
} else {
    $returned_id = $this->con->insert_id;  // maintain object-oriented syntax
    $stmt->close();
}
  • 带有PHP_URL_QUERY 标志的parse_url() 将从url 查询中生成一个字符串(? 之后的所有内容)。
  • parse_str() 会将查询字符串转换为数组。 $array 是接收转换后数据的指定变量。
  • 您可以通过$array 中的v 键访问视频ID。
  • 我已删除 stmt_init() 调用,因为我更喜欢在脚本中进行更少的调用。
  • 因为只有真正需要占位符和绑定不安全和可能不稳定的值,所以我鼓励您简化准备好的语句。
    • 硬编码no0 值。
    • NULL 用于AUTOINCREMENT 列。
    • 正如我在评论中所说,最佳实践表明您应该只将视频 ID 存储在您的数据库表中,以减少内存使用并提高数据可维护性。
    • NOW() 用于date_added(假设您要存储日期时间标记)。
  • 为了方便调试,我内置了一些条件。
  • 获取insert_id 时,请务必保持面向对象的语法。

【讨论】:

  • ...谢谢你,抱歉我出差了。是的,我知道投票是一种回报,我非常感谢这个答案。您是对的,当您只需要 v= 时,像我所做的那样将所有 html 存储在 dB 中是多余的。效率更高。
  • 挑战在于当我使用单独的加载帖子函数调用它时。我必须解决这个问题才能使这项工作按预期进行。
  • 我不明白你在说什么,但我向你保证,在你的代码中实现我的 sn-p 是值得的。
【解决方案2】:

您存储的都是错误的!您不需要数据库中的所有废话,只需要视频 ID:

<?php

$body = 'https://www.youtube.com/watch?v=h2v5jh9hy-Y';
$body = parse_url($body);
parse_str($body['query'], $query);

// This is what should go in your DB
$video = $query['v'];

// And here's how you output it
echo '<br><iframe width="420" height="315" src="https://www.youtube.com/embed/' . $video . '"></iframe><br>';

在这里查看:https://3v4l.org/kdAq4

【讨论】:

  • 谢谢你,但我有一个单独的函数来加载使这种格式不兼容的帖子。如果这是从 dB 调用的内容,我可以在其中放置一个 if 语句来显示 iframe,但我的方式似乎更容易。
猜你喜欢
  • 2015-02-04
  • 2017-09-14
  • 2012-07-03
  • 1970-01-01
  • 2017-04-28
  • 2020-07-22
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
相关资源
最近更新 更多