データベース
まず、ベース自体を取得する必要があります。 RuTrackerは毎月ここでトレントをダンプします 。 2ダースのCSVファイルをダウンロードして展開します。
トレントに関する情報を持っているものだけが必要です。残りは削除されます。 ファイル「category_info.csv」-各ファイルを開きたくない人のためのヒント(削除:「category_1.csv」、「category_4.csv」、「category_36.csv」)。 残りのファイルを開いて、そのような構造を確認します(「;」文字をすぐに新しい行に置き換えました。これは視覚的に便利です)。
「1568」 | RuTrackerのセクションID |
「料理」 | セクションタイトル |
「63629」 | RuTrackerのトピックID |
「F7D7BE97A818CCDFA072C42348EB669F7883888D」 | ハッシュトレント |
「(料理)おいしい物語1」 | トレント名 |
「729927066」 | バイト単位の配信サイズ |
2006-08-21 10:00:22 | 配布日 |
次に、すべての情報をデータベースに追加します。 MySQLを最も一般的なデータベースとして使用します。 ここにそのようなテーブルがあります(注:ハッシュ列は一意であり、すべてのテキストデータはutf8エンコーディングです):
SQLテーブル
CREATE TABLE IF NOT EXISTS `torrents` ( `id` int(11) NOT NULL, `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `hash` varchar(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `date` date NOT NULL, `size` int(11) NOT NULL, `topic_id` int(11) NOT NULL, `cat_id` int(11) NOT NULL, `cat_name` varchar(120) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf32 COLLATE=utf32_bin; ALTER TABLE `torrents` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `hash` (`hash`); ALTER TABLE `torrents` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
次に、サーバー上のすべてのCSVファイルを1つのフォルダーにアップロードします(たとえば、「db」と呼びます)。 以下に示す簡単なスクリプトを使用して、トレントに関する情報をデータベースに追加できます。 また、ソースCSVファイルと同じフォルダーにアップロードする必要があります。
ファイルinsert_to_db.php
<? // 3- set_time_limit(180); // MySQL, mysql_connect("localhost", "torrent", "password") or die("Could not connect to MySQL"); // , mysql_select_db("torrent") or die("Could not select database"); // utf8 mysql_query("SET NAMES utf8"); // url "f" $fp = fopen($_GET[f], "r"); // while (!feof($fp)) { // (, trim() , "") $tmp = trim(fgets($fp)); // . ";" $torrent = explode('";"', $tmp); // " $torrent[0] = substr($torrent[0], 1); $torrent[6] = substr($torrent[6], 0, (strlen($torrent[6]) - 1)); // , //print '<pre>'; print_r($torrent); exit(); // mysql_query("INSERT INTO `torrents` (`name`, `hash`, `date`, `size`, `topic_id`, `cat_id`, `cat_name`) VALUES ('" . mysql_real_escape_string($torrent[4]) . "', '" . $torrent[3] . "', '" . $torrent[6] . "', '" . $torrent[5] . "', '" . $torrent[2] . "', '" . $torrent[0] . "', '" . mysql_real_escape_string($torrent[1]) . "') "); } // fclose($fp); // print 'complete: ' . $_GET[f]; ?>
ブラウザを開き、URL「http://site.ru/db/insert_to_db.php?f=category_10.csv」を開きます。 各CSVファイルについても同じことを行います。 はい、これはすべて自動化できますが、すべてができる限り明確になるように具体的に書きました。 これらのアクションの後、160万件を超えるレコードがテーブルに表示されました。 小さなベースではありません。 この量のデータを使用したMySQL検索では処理できないため、このタスクをSphinxに任せましょう。
スフィンクス
Sphinxのさまざまなシステムへのインストールは、さまざまな方法で行われます。 それはすべて、オペレーティングシステムとハードウェアに依存します。 このトピックは別の記事に値します。 しかし、インターネットには非常に多くの優れたマニュアルがあります。 ロシア語でも。 次に、Sphinxの構成ファイルをセットアップします。 キャッシュなど、サイトのルートディレクトリにディレクトリを作成します。 サイトのすべてのSphinxインデックスファイルはここに保存されます。 構成ファイルをこのフォルダーにロードします(リストを以下に示します)。
Torrents.confファイル
# source torrentz { # type = mysql sql_host = localhost sql_user = torrent sql_pass = password sql_db = torrent sql_port = 3306 # utf8 sql_query_pre = SET NAMES utf8 sql_query_pre = SET CHARACTER SET utf8 # sql_query = SELECT id, name FROM torrents # ( ) . sql_ranged_throttle = 0 } # . Sphinx index torrentz { # source = torrentz # path = /home/rutr/rutracker.online/www/cache/ # docinfo = extern # morphology = stem_enru # min_word_len = 2 # charset_type = utf-8 # charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F # min_infix_len = 2 # "*" enable_star = 1 } # indexer { # mem_limit = 32M } # searchd { # listen = 127.0.0.1:3312 # log = /home/rutr/rutracker.online/www/cache/searchd.log # query_log = /home/rutr/rutracker.online/www/cache/query.log # read_timeout = 5 # - max_children = 30 # pid- pid_file = /home/rutr/rutracker.online/www/cache/searchd.pid # - max_matches = 1000 }
sshを介してサーバーに接続します。 Sphinxがデータベースを検索できるようにするには、インデックスを準備する必要があります。 コマンドを実行します。
indexer --config /home/rutr/rutracker.online/www/cache/torrents.conf –all
Sphinxはしばらくの間、データベースインデックスをホストします。 期間はサーバーの容量に依存します。 私の場合、インデックス作成には約10分かかりました。
インデックス作成の終了後、すべてがうまくいったかどうかをチェックします。 これを行うには、次のコマンドを使用してコンソールで検索を実行します(検索フレーズは、構成ファイルを指定した後に書き込まれます)。
search --config /home/rutr/rutracker.online/www/cache/torrents.conf morrowind mod
上のスクリーンショットに似たものを見たら、インデックス作成は成功しました。 何も見つからない場合は、次のコマンドを実行する必要はありません。 Sphinx検索デーモンを起動するには、次のコマンドを実行します。
searchd --config /home/rutr/rutracker.online/www/cache/torrents.conf
再起動するたびにデーモンを起動する必要があることに注意してください。 デーモンをオフにするには(必要な場合)、上記のコマンドの最後に「--stop」を追加します。
Web
Webインターフェースに使用するフレームワークについては考えていませんでした。 要件は単純です。使いやすさ、レスポンシブデザイン、最新のすべてのブラウザーのサポートです。 この下では、Bootstrapが少し退屈ですが、素晴らしいです。 配布キットをダウンロードする必要はなく、スタイルシートをオンラインで接続できます。 メインページはPHPを使用しない純粋なHTMLです。 コードへのコメントは不要だと思います。
Index.phpファイル
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" href="/favicon.ico"> <title> RuTracker</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> <style type="text/css"> .inCenter { margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; } .inCenter.isResp { width: 50%; height: 50%; min-width: 400px; max-width: 800px; padding: 40px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="inCenter isResp"> <div class="col-sm-12 col-md-10 col-md-offset-1"> <form action="search.php" method="GET"> <div class="form-group text-center"> <h1> RuTracker</h1> </div> <div class="form-group input-group"> <input class="form-control input-lg" type="text" name="q" placeholder=""/> <span class="input-group-btn"> <button class="btn btn-primary input-lg" type="submit"><i class="glyphicon glyphicon-search"></i></button> </span> </div> </form> </div> </div> </div> </div> </body> </html>
= "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"整合性= "sha384-1q8mTJOASx8j1Au + a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin = "匿名"> <!DOCTYPE html> <html lang="ru"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" href="/favicon.ico"> <title> RuTracker</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> <style type="text/css"> .inCenter { margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; } .inCenter.isResp { width: 50%; height: 50%; min-width: 400px; max-width: 800px; padding: 40px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="inCenter isResp"> <div class="col-sm-12 col-md-10 col-md-offset-1"> <form action="search.php" method="GET"> <div class="form-group text-center"> <h1> RuTracker</h1> </div> <div class="form-group input-group"> <input class="form-control input-lg" type="text" name="q" placeholder=""/> <span class="input-group-btn"> <button class="btn btn-primary input-lg" type="submit"><i class="glyphicon glyphicon-search"></i></button> </span> </div> </form> </div> </div> </div> </div> </body> </html>
メインページのデザインは、非常に最小限で機能的なものであることがわかりました。
検索スクリプトはさらに興味深いものになります。 まず、PHPのSphinx APIが必要です。 最新バージョンはこちらから入手できます 。 検索スクリプトがどのように機能するか、リストでさらに説明します。 ファイルを接続してAPIを操作し、検索を構成し、検索し、検索結果を便利な形式で投稿します。 追加のクリックなしで、検索からトレントを直接ダウンロードできます。
ファイルsearch.php
<? // $q=trim(urldecode($_GET[q])); // , if (empty($q)) {header("Location: /"); exit();} // , ... // MySQL, mysql_connect("localhost", "torrent", "password") or die("Could not connect to MySQL"); // , mysql_select_db("torrent") or die("Could not select database"); // utf8 mysql_query("SET NAMES utf8"); // API Sphinx include("sphinxapi.php"); // Sphinx $sphinx=new SphinxClient(); // Sphinx-. "torrents.conf" $sphinx->SetServer('localhost', 3312); // $sphinx->SetMatchMode(SPH_MATCH_ANY); // $sphinx->SetSortMode(SPH_SORT_RELEVANCE); // 50 . $sphinx->SetLimits(0, 50); // (* - "torrents.conf", : torrentz) $torrents=$sphinx->Query($q, '*'); // , //print $sphinx->getLastError(); //print '<br><pre>'; print_r($torrents); exit(); // , . . - . function bytesToSize($bytes, $precision = 0) { $kilobyte = 1024; $megabyte = $kilobyte * 1024; $gigabyte = $megabyte * 1024; $terabyte = $gigabyte * 1024; if (($bytes >= 0) && ($bytes < $kilobyte)) {return $bytes . ' B';} elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {return round($bytes / $kilobyte, $precision) . ' Kb';} elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {return round($bytes / $megabyte, $precision) . ' Mb';} elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {return round($bytes / $gigabyte, $precision) . ' Gb';} elseif ($bytes >= $terabyte) {return round($bytes / $terabyte, $precision) . ' Tb';} else {return $bytes . ' B';} } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" href="/favicon.ico"> <title><?=htmlspecialchars($q)?></title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> <style type="text/css"> body { padding-top: 80px; padding-bottom: 20px; } </style> </head> <body> <nav class="navbar navbar-default navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/"> RuTracker</a> </div> <div id="navbar" class="navbar-collapse collapse"> <form action="/search.php" method="GET" class="navbar-form navbar-left"> <div class="form-group input-group"> <input type="text" placeholder="" value="<?=htmlspecialchars($q)?>" class="form-control" name="q"> <span class="input-group-btn"> <button class="btn btn-primary" type="submit"><i class="glyphicon glyphicon-search"></i></button> </span> </div> </form> </div> <!--/.navbar-collapse --> </div> </nav> <div class="container"> <h1><?=htmlspecialchars($q)?></h1> <table class="table table-striped"> <caption> : <?=$torrents[total_found]?></caption> <tbody> <? // $ids = array_keys($torrents[matches]); // id- SQL $ids = implode(',', $ids); // SQL $sql="SELECT `id`, `name`, `hash`, `date`, `size` FROM `torrents` WHERE `id` IN (".$ids.") ORDER BY FIELD(`id`, ".$ids.")"; // SQL $r=mysql_query($sql); // for ($i=0; $i < mysql_num_rows($r); $i++) { // $f=mysql_fetch_array($r); // $torrent_date=explode('-', $f[date]); // , $torrent_date=$torrent_date[2].'.'.$torrent_date[1].'.'.$torrent_date[0]; ?> <tr> <td width="75%"><a href="/torrent.php?id=<?=$f[id]?>"><?=$f[name]?></a></td> <td width="5%"><a href="magnet:?xt=urn:btih:<?=$f[hash]?>"><i class="glyphicon glyphicon-magnet"></i></a></td> <td width="10%"><?=bytesToSize($f[size])?></td> <td width="10%"><?=$torrent_date?></td> </tr> <? } ?> </tbody> </table> </div> <!-- /.container --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="http://getbootstrap.com/dist/js/bootstrap.min.js"></script> </body> </html>
= "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"整合性= "sha384-1q8mTJOASx8j1Au + a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin = "匿名"> <? // $q=trim(urldecode($_GET[q])); // , if (empty($q)) {header("Location: /"); exit();} // , ... // MySQL, mysql_connect("localhost", "torrent", "password") or die("Could not connect to MySQL"); // , mysql_select_db("torrent") or die("Could not select database"); // utf8 mysql_query("SET NAMES utf8"); // API Sphinx include("sphinxapi.php"); // Sphinx $sphinx=new SphinxClient(); // Sphinx-. "torrents.conf" $sphinx->SetServer('localhost', 3312); // $sphinx->SetMatchMode(SPH_MATCH_ANY); // $sphinx->SetSortMode(SPH_SORT_RELEVANCE); // 50 . $sphinx->SetLimits(0, 50); // (* - "torrents.conf", : torrentz) $torrents=$sphinx->Query($q, '*'); // , //print $sphinx->getLastError(); //print '<br><pre>'; print_r($torrents); exit(); // , . . - . function bytesToSize($bytes, $precision = 0) { $kilobyte = 1024; $megabyte = $kilobyte * 1024; $gigabyte = $megabyte * 1024; $terabyte = $gigabyte * 1024; if (($bytes >= 0) && ($bytes < $kilobyte)) {return $bytes . ' B';} elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {return round($bytes / $kilobyte, $precision) . ' Kb';} elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {return round($bytes / $megabyte, $precision) . ' Mb';} elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {return round($bytes / $gigabyte, $precision) . ' Gb';} elseif ($bytes >= $terabyte) {return round($bytes / $terabyte, $precision) . ' Tb';} else {return $bytes . ' B';} } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" href="/favicon.ico"> <title><?=htmlspecialchars($q)?></title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> <style type="text/css"> body { padding-top: 80px; padding-bottom: 20px; } </style> </head> <body> <nav class="navbar navbar-default navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/"> RuTracker</a> </div> <div id="navbar" class="navbar-collapse collapse"> <form action="/search.php" method="GET" class="navbar-form navbar-left"> <div class="form-group input-group"> <input type="text" placeholder="" value="<?=htmlspecialchars($q)?>" class="form-control" name="q"> <span class="input-group-btn"> <button class="btn btn-primary" type="submit"><i class="glyphicon glyphicon-search"></i></button> </span> </div> </form> </div> <!--/.navbar-collapse --> </div> </nav> <div class="container"> <h1><?=htmlspecialchars($q)?></h1> <table class="table table-striped"> <caption> : <?=$torrents[total_found]?></caption> <tbody> <? // $ids = array_keys($torrents[matches]); // id- SQL $ids = implode(',', $ids); // SQL $sql="SELECT `id`, `name`, `hash`, `date`, `size` FROM `torrents` WHERE `id` IN (".$ids.") ORDER BY FIELD(`id`, ".$ids.")"; // SQL $r=mysql_query($sql); // for ($i=0; $i < mysql_num_rows($r); $i++) { // $f=mysql_fetch_array($r); // $torrent_date=explode('-', $f[date]); // , $torrent_date=$torrent_date[2].'.'.$torrent_date[1].'.'.$torrent_date[0]; ?> <tr> <td width="75%"><a href="/torrent.php?id=<?=$f[id]?>"><?=$f[name]?></a></td> <td width="5%"><a href="magnet:?xt=urn:btih:<?=$f[hash]?>"><i class="glyphicon glyphicon-magnet"></i></a></td> <td width="10%"><?=bytesToSize($f[size])?></td> <td width="10%"><?=$torrent_date?></td> </tr> <? } ?> </tbody> </table> </div> <!-- /.container --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="http://getbootstrap.com/dist/js/bootstrap.min.js"></script> </body> </html>
ユーザーの利便性のために、各トレントに対して個別のページを作成します。 突然誰かがリンクを送信する必要があります。
torrent.phpファイル
<? // id $id=trim(urldecode($_GET[id])); // id, if (empty($id)) {header("Location: /"); exit();} // id , ... // MySQL, mysql_connect("localhost", "torrent", "password") or die("Could not connect to MySQL"); // , mysql_select_db("torrent") or die("Could not select database"); // utf8 mysql_query("SET NAMES utf8"); // SQL id $sql="SELECT * FROM `torrents` WHERE `id`='".mysql_real_escape_string($id)."'"; // SQL $r=mysql_query($sql); // id , if (mysql_num_rows($r)==0) {header("Location: /"); exit();} // $torrent=mysql_fetch_array($r); // $torrent_date=explode('-', $torrent[date]); $torrent_date=$torrent_date[2].'.'.$torrent_date[1].'.'.$torrent_date[0]; // , . . - . function bytesToSize($bytes, $precision = 0) { $kilobyte = 1024; $megabyte = $kilobyte * 1024; $gigabyte = $megabyte * 1024; $terabyte = $gigabyte * 1024; if (($bytes >= 0) && ($bytes < $kilobyte)) {return $bytes . ' B';} elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {return round($bytes / $kilobyte, $precision) . ' Kb';} elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {return round($bytes / $megabyte, $precision) . ' Mb';} elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {return round($bytes / $gigabyte, $precision) . ' Gb';} elseif ($bytes >= $terabyte) {return round($bytes / $terabyte, $precision) . ' Tb';} else {return $bytes . ' B';} } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" href="/favicon.ico"> <title><?=htmlspecialchars($torrent[name])?></title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> <style type="text/css"> body { padding-top: 80px; padding-bottom: 20px; } </style> </head> <body> <nav class="navbar navbar-default navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/"> RuTracker</a> </div> <div id="navbar" class="navbar-collapse collapse"> <form action="/search.php" method="GET" class="navbar-form navbar-left"> <div class="form-group input-group"> <input type="text" placeholder="" value="" class="form-control" name="q"> <span class="input-group-btn"> <button class="btn btn-primary" type="submit"><i class="glyphicon glyphicon-search"></i></button> </span> </div> </form> </div> <!--/.navbar-collapse --> </div> </nav> <div class="container"> <h1><?=htmlspecialchars($torrent[name])?></h1> <table class="table table-striped"> <tbody> <tr> <th width="20%">:</th> <td><a href="magnet:?xt=urn:btih:<?=$torrent[hash]?>"><i class="glyphicon glyphicon-magnet"></i> Magnet</a></td> </tr> <tr> <th width="20%">:</th> <td><?=bytesToSize($torrent[size])?></td> </tr> <tr> <th width="20%"> :</th> <td><?=$torrent_date?></td> </tr> <tr> <th width="20%">:</th> <td><a target=_blank href="http://rutracker.org/forum/viewforum.php?f=<?=$torrent[cat_id]?>"><?=htmlspecialchars($torrent[cat_name])?></a></td> </tr> <tr> <th width="20%">:</th> <td><a target=_blank href="http://rutracker.org/forum/viewtopic.php?t=<?=$torrent[topic_id]?>"> #<?=$torrent[topic_id]?></a></td> </tr> </tbody> </table> </div> <!-- /.container --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="http://getbootstrap.com/dist/js/bootstrap.min.js"></script> </body> </html>
= "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"整合性= "sha384-1q8mTJOASx8j1Au + a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin = "匿名"> <? // id $id=trim(urldecode($_GET[id])); // id, if (empty($id)) {header("Location: /"); exit();} // id , ... // MySQL, mysql_connect("localhost", "torrent", "password") or die("Could not connect to MySQL"); // , mysql_select_db("torrent") or die("Could not select database"); // utf8 mysql_query("SET NAMES utf8"); // SQL id $sql="SELECT * FROM `torrents` WHERE `id`='".mysql_real_escape_string($id)."'"; // SQL $r=mysql_query($sql); // id , if (mysql_num_rows($r)==0) {header("Location: /"); exit();} // $torrent=mysql_fetch_array($r); // $torrent_date=explode('-', $torrent[date]); $torrent_date=$torrent_date[2].'.'.$torrent_date[1].'.'.$torrent_date[0]; // , . . - . function bytesToSize($bytes, $precision = 0) { $kilobyte = 1024; $megabyte = $kilobyte * 1024; $gigabyte = $megabyte * 1024; $terabyte = $gigabyte * 1024; if (($bytes >= 0) && ($bytes < $kilobyte)) {return $bytes . ' B';} elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {return round($bytes / $kilobyte, $precision) . ' Kb';} elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {return round($bytes / $megabyte, $precision) . ' Mb';} elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {return round($bytes / $gigabyte, $precision) . ' Gb';} elseif ($bytes >= $terabyte) {return round($bytes / $terabyte, $precision) . ' Tb';} else {return $bytes . ' B';} } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" href="/favicon.ico"> <title><?=htmlspecialchars($torrent[name])?></title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> <style type="text/css"> body { padding-top: 80px; padding-bottom: 20px; } </style> </head> <body> <nav class="navbar navbar-default navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/"> RuTracker</a> </div> <div id="navbar" class="navbar-collapse collapse"> <form action="/search.php" method="GET" class="navbar-form navbar-left"> <div class="form-group input-group"> <input type="text" placeholder="" value="" class="form-control" name="q"> <span class="input-group-btn"> <button class="btn btn-primary" type="submit"><i class="glyphicon glyphicon-search"></i></button> </span> </div> </form> </div> <!--/.navbar-collapse --> </div> </nav> <div class="container"> <h1><?=htmlspecialchars($torrent[name])?></h1> <table class="table table-striped"> <tbody> <tr> <th width="20%">:</th> <td><a href="magnet:?xt=urn:btih:<?=$torrent[hash]?>"><i class="glyphicon glyphicon-magnet"></i> Magnet</a></td> </tr> <tr> <th width="20%">:</th> <td><?=bytesToSize($torrent[size])?></td> </tr> <tr> <th width="20%"> :</th> <td><?=$torrent_date?></td> </tr> <tr> <th width="20%">:</th> <td><a target=_blank href="http://rutracker.org/forum/viewforum.php?f=<?=$torrent[cat_id]?>"><?=htmlspecialchars($torrent[cat_name])?></a></td> </tr> <tr> <th width="20%">:</th> <td><a target=_blank href="http://rutracker.org/forum/viewtopic.php?t=<?=$torrent[topic_id]?>"> #<?=$torrent[topic_id]?></a></td> </tr> </tbody> </table> </div> <!-- /.container --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="http://getbootstrap.com/dist/js/bootstrap.min.js"></script> </body> </html>
以上です。 RuTrackerのデータベースを使用した完全に機能するWebサイトを取得しました。クイック検索と便利なインターフェイスがあります。 具体的には、カテゴリ、並べ替え、ページネーションなどによる検索フィルタリングを追加しませんでした。そのため、最も必要なコードが最もクリーンになります。 関心がある場合は、コメントまたは別の記事でこれについて全員に伝えます。
ご清聴ありがとうございました。 質問を書いて、みんなに答えます。