将PHP下载脚本合并到`unctions.php`中

时间:2013-03-21 作者:Marc Dingena

我在WordPress上运行一个大型混音带下载站点。我目前正在开发一个新主题,我希望在主题中包含尽可能多的站点功能functions.php.

为了提供下载服务,我有几个PHP脚本。访问者通过单击URL调用下载(示例):http://www.tjoonz.com/house.php?id=1234&file=post-slug.
脚本清理参数并为MP3 来自专用服务器目录的文件。我主要担心的是这些脚本包含数据库连接细节,这是我更愿意使用的$wpdb 对于

当前脚本(供参考)

如果这有点过分,我深表歉意,但以后可能会派上用场。如果你只是在读我的问题,现在可能可以跳过这一点。

PHP

<?php // Tjoonz.com download script v1.2

// test arguments
if(!isset($_REQUEST[\'id\']) || empty($_REQUEST[\'id\']) || !isset($_REQUEST[\'file\']) || empty($_REQUEST[\'file\'])) 
{
    // invalid argument(s), abort script
    header("HTTP/1.0 400 Bad Request");
    die();
}

// set variables
$current_time = time();
$user_ip = $_SERVER[\'REMOTE_ADDR\'];
$post_id = $_GET[\'id\'];
$file_requested = $_GET[\'file\'];
$file_name = strip_tags($file_requested);
$file_path = \'/home/tjoonz/audio/house/\';
$locked = false;

// test if cookie \'downloadsAllowed\' is set
// this prevents hotlinking on other domains for users who haven\'t visited Tjoonz.com yet
if ($_COOKIE["downloadsAllowed"] == "tj00nz")
{   
    $file_full = $file_path.$file_name;
    if (file_exists($file_full)) // test if requested mixtape exists
    {
        // establish connection to database for Play Counter test
        $user="#######";
        $password="#######";
        $database="#######";
        $host="#######";
        mysql_connect($host,$user,$password);
        mysql_select_db($database) or die(mysql_error());

        // set timerange to 2 hours ago (right now minus 7200 seconds)
        $timerange = $current_time - 7200;
        // get all records from \'playcount_lock\' table
        $locks = mysql_query("SELECT * FROM playcount_lock WHERE request_time > $timerange") or die(mysql_error()); 

        // test if current IP address has already accessed this mixtape in the last 2 hours
        while ($lock = mysql_fetch_object($locks))
        {
            // set variables with data from record
            $lock_ip = $lock->ip_address;
            $lock_id = $lock->post_id;
            $lock_time = $lock->request_time;

            // compare record data with current user data
            if($lock_ip == $user_ip && $lock_id == $post_id && ($lock_time + 7200) >= $current_time)
            {
                // match found, break out of while loop and continue with script
                $locked = true;
                break;
            }
        }

        if (!$locked) // if playcounter is not locked, update the database
        { 
            // add a lock entry for the next two hours
            mysql_query("INSERT INTO `playcount_lock` (`request_time`, `post_id`, `ip_address`) VALUES (\'$current_time\', \'$post_id\', \'$user_ip\')") or die(mysql_error());

            // update the play counter for this mixtape
            $post_meta = mysql_query("SELECT meta_value FROM `wp_postmeta` WHERE `meta_key` = \'_played\' AND `post_id` = ".$post_id);
            $count = @mysql_result($post_meta, 0);

            if($count == FALSE)
            {
                // if no plays are present, insert the metadata into table
                mysql_query("INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (".$post_id.",\'_played\',1)");
            }
            else
            {
                // otherwise increase the existing number of plays by 1
                $newCount = mysql_result($post_meta, 0) + 1;
                mysql_query("UPDATE `wp_postmeta` SET meta_value = ".$newCount." WHERE `meta_key` = \'_played\' AND `post_id` = ".$post_id);
            }
        }

        // we\'re done with the database, kill the connection
        mysql_close();

        // finally, send the file
        header("X-SENDFILE: ".$file_full);
        header("Content-Type: audio/mpeg");
        header("Content-Disposition: attachment; filename=".basename($file_full));
        header("Content-Length: ".filesize($file_full));
        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: public");
        header("Content-Description: File Transfer");
        header("Content-Transfer-Encoding: binary");
    }
    else // couldn\'t find that mixtape
    {
        header(\'HTTP/1.0 404 Not Found\');
    }

}
else // cookie \'downloadsAllowed\' not set, redirecting user to mixtape page
{
    $file_redirection = substr($file_name,0, -4);
    header("Location: http://www.tjoonz.com/house/" . $file_redirection . "/");
}

?>

JS

// when playnow is clicked, add to myPlaylist and immediately start playing the mixtape
$("body").on("click", ".jplayer-playnow", function (e) {
    e.preventDefault();

    // add to Play Queue and play it immediately
    $.jPlayer.timeFormat.showHour = true;
    $.jPlayer.timeFormat.sepHour = ":";
    $.jPlayer.timeFormat.sepMin = ":";
    $.jPlayer.timeFormat.sepSec = "";
    myPlaylist.add({
        title: $(".single-title-mixtape").text(),
        artist: $(".single-title-artist").text(),
        genre: $(".jplayer-playnow span").attr("class"),
        mp3: $(this).attr("href"),                       // <--- This is where my problem comes up for my new theme, keep reading
        poster: $(".wp-post-image").attr("src")
    }, true); // true value here makes the newly added track play immediately
});
意图我使用当前脚本有两个方面:当用户单击PLAY 按钮,jQuery阻止链接被导航到,并使用URL指示音乐播放器获取文件。当用户单击DOWNLOADS 按钮,浏览器只需继续,即可启动直接下载。两个按钮使用相同的脚本和相同的URL。

在我的新脚本中,我想合并house.php, electro.php, dubstep.php, drum-and-bass.phptechno.php 使用一个脚本genre 参数此外,根据接下来的情况,我将添加一个参数来指定action (下载或播放)。

我打算将脚本完全嵌入其中functions.php. 在混音带页面上,有两个链接:

<!--Play-->
<a href="?id=<?php echo $post->ID; ?>&file=<?php tjnz_slug(); ?>&genre=<?php echo $category[0]->category_nicename; ?>&action=play">Play</a>
<!--Download-->
<a href="?id=<?php echo $post->ID; ?>&file=<?php tjnz_slug(); ?>&genre=<?php echo $category[0]->category_nicename; ?>&action=download">Download</a>
问题是,在我的旧脚本中,我只是捕获了播放链接(按锚点上的类名),并阻止了默认的浏览器操作,然后执行我的操作。我之所以能够这样做,是因为我可以指向“真实”文件(例如。house.php).

如果我把密码插进去functions.php, 如何指示音乐播放器音频文件的位置?音频文件不一定必须是MP3 文件,正如我当前的代码所显示的:我指示jPlayer音频文件位于房子里。例如php。

我如何告诉jPlayer文件现在来自神秘的functions.php? 我是否直接链接到theme dir/functions.php? 听起来不是个好主意,但那只是我的直觉。

就像我之前说的,我想把剧本放在里面的主要原因functions.php 这样我就可以利用$wpdb. 如果仍然需要一个单独的PHP文件,我仍然会接受这个答案(前提是你支持这个理论)。

1 个回复
最合适的回答,由SO网友:user28206 整理而成

你不会直接从functions.php 按URL引用的文件。

这个functions.php 与WordPress主题一起加载,它使主题模板文件中的功能对您可用。

大多数代码可以直接移植到functions.php 但您必须围绕它包装一些可以在页面模板中调用的接口。

如果我这样做,我可能会在索引中放入一些PHP代码。php的主题,右a在顶部看看$_REQUEST 对象,就像您在PHP代码开始时所做的那样。

然后,您将调用functions.php 处理实际DB连接并为文件提供服务的文件。

正如您所提到的,您必须使用$wpdb 全局变量来读取表,好消息是,因为您在WordPress会话中工作,所以不需要向DB进行身份验证,因此没有UN/PW信息。

您的JS最好在主题中的一个单独文件中提供,并通过使用wp_enqueue_script.

结束

相关推荐

$wpdb->GET_RESULTS的速度优化

我使用这段代码从所有帖子中为名为“autor”的自定义字段生成所有自定义字段值。<?php $autor = $wpdb->get_results(\"SELECT meta_value AS autor FROM wp_posts, wp_postmeta WHERE post_status = \'publish\' AND meta_key = \'autor\' GROUP BY meta_value ORDER BY meta_value\") ?> <ol>