問題描述
我真的希望有人花一點時間查看我的代碼.我正在解析一些新聞內容,我可以將初始解析插入到包含新聞 URL 和標題的數據庫中.我想進一步擴展它,傳遞每個文章鏈接并解析文章的內容并將其包含在我的數據庫中.初始解析的工作原理如下:
find('div[class=mainBlock]', 0);$items = array();foreach ($main->find('a') as $m){$items[] = '("'.mysql_real_escape_string($m->純文本).'","'.mysql_real_escape_string($m->href).'")';}$reverse = array_reverse($items);mysql_query ("INSERT IGNORE INTO bag_news (article, link) VALUES".(implode(',', $reverse))."");?>
如您所見,我使用的是 PHP 簡單 HTML DOM 解析器. 為了擴展,我是嘗試使用 mysqli 語句,我可以在其中綁定參數,以便將所有 html 標記插入到我的數據庫中.我以前用 XML 解析做過這個.問題是我不知道如何綁定數組,看看我的代碼是否正確,是否可以這樣工作......這是完整的代碼:
query("SET NAMES 'utf8'");include_once ('simple_html_dom.php');$html = file_get_html('http://basket-planet.com/ru/');//查找主要新聞$main = $html->find('div[class=mainBlock]', 0);$items = array();foreach ($main->find('a') as $m){$h = file_get_html('http://www.basket-planet.com'.$m->href.'');$article = $h->find('div[class=newsItem]');//轉成字符串可以修改內容$a = str_get_html(implode("
", (array)$article));if(isset($a->find('img'))){foreach ($a->find('img') as $img){$img->outertext = '';}}//去掉圖片if(isset($a->find('a'))){foreach ($a->find('a') as $link){$link->href = 'javascript:;';$link->target = '';}}//去掉任何javascriptif(isset($a->find('iframe'))){foreach ($a->find ('iframe') as $frame){$frame->outertext = '';}}//去掉 iframe@$a->find('object', 0)->outertext = '';@$a->find('object', 1)->outertext = '';//修改更多內容以僅檢索文本內容//將整個內容放入一個 div 中(如果語句在這里有效???)$text_content = ''.$a.'
'.($a->find('object', 0)->data > 0 ?'find('object', 0)->data.'">播放視頻</a> ')($a->find('object', 1)->data > 0 ?'find('object', 1)->data.'">播放視頻</a> ')($a->find('iframe[src*=youtube]', 0)->src > 0 ?'<a target="_blank" href="'.$a->find('iframe', 0)->src.'">播放視頻</a> ')//進行更多檢查以查看是否存在視頻鏈接.'</div>';$items[] = '("'.$m->plaintext.'","'.$m->href.'","'.$text_content.'")';}//反轉數組,使最新的項目具有最后一個ID$reverse = array_reverse($items);$stmt = $mysqli->prepare ("INSERT IGNORE INTO test_news (article, link, text_cont) VALUES (?,?,?)");$stmt->bind_param ???;//(內爆(',', $reverse));$stmt->execute();$stmt->close();?>所以邏輯是針對找到的文章的每個 href,我傳遞它來解析內容,并嘗試將其添加到數組中.我可能有很多錯誤,但我還不能測試它,因為我不知道如何綁定它以查看它是否有效.而且我也不確定是否可以在 $text_content div 中執行 if 語句...意思是顯示播放視頻"(如果存在).所以,如果有人能花時間和我一起解決這個問題,我將不勝感激.
更新:將 $text_content div 中的 if 語句更改為比較運算符.
解決方案 這正是 mysqli 真正尷尬的場景.要綁定多個參數,您必須將它們全部作為可變長度參數列表傳遞給 mysql->bind_param(),但棘手的部分是您必須通過引用綁定它們.PHP 中的引用可能非常混亂.
這是一個粗略的例子(雖然我沒有測試過這個確切的代碼):
$stmt = $mysqli->prepare("INSERT IGNORE INTO test_news(文章, 鏈接, text_cont) VALUES (?,?,?)");foreach ($reverse as &$value) {$params[] = &$value;}array_unshift(str_repeat('s', count($params)));call_user_func_array(array($stmt, 'bind_param'), $params);
當我想編寫一個通用函數來將參數綁定到 SQL 時,我發現使用 PDO 要容易得多.不需要綁定,只需將一組值傳遞給 PDOStatement::execute() 方法即可.
$stmt = $pdo->prepare("INSERT IGNORE INTO test_news(文章, 鏈接, text_cont) VALUES (?,?,?)");$stmt->execute($reverse);
<小時>
更新:如果您需要 $items 來包含多行數據,我會這樣做:
首先,在構建 $items 時,將其設為數組數組,而不是將值連接在一起:
foreach ($main->find('a') as $m){$items[] = array($m->plaintext, $m->href, $text_content);}
然后準備一個插入一行的 INSERT 語句,并在 $items 上為每個元組循環執行一次準備好的語句:
$stmt = $pdo->prepare("INSERT INTO test_news(文章, 鏈接, text_cont) VALUES (?,?,?)");foreach ($items as $tuple) {$stmt->execute($tuple);}
我完全不知道你為什么使用 array_reverse(),我也不知道你為什么使用 INSERT IGNORE,所以我忽略了這些.
I would really like for someone to take a little time and look over my code. I'm parsing some news content and I can insert the initial parse into my database which contains the news URL and the title. I'd like to expand it farther, to pass along each article link and parse the content of the article and include it in my database. The initial parsing works perfectly like this:
<?php
include_once ('connect_to_mysql.php');
include_once ('simple_html_dom.php');
$html = file_get_html('http://basket-planet.com/ru/');
$main = $html->find('div[class=mainBlock]', 0);
$items = array();
foreach ($main->find('a') as $m){
$items[] = '("'.mysql_real_escape_string($m->plaintext).'",
"'.mysql_real_escape_string($m->href).'")';
}
$reverse = array_reverse($items);
mysql_query ("INSERT IGNORE INTO basket_news (article, link) VALUES
".(implode(',', $reverse))."");
?>
As you can see, I'm using PHP Simple HTML DOM Parser. To expand, I'm trying to use mysqli statement where I can bind the parameters so all the html tags get inserted into my database. I've done this before with XML parsing. Problem is I don't know how to bind the array, and see whether my code is correct, if it will work this way... Here's the entire code:
<?php
$mysqli = new mysqli("localhost", "root", "", "test");
$mysqli->query("SET NAMES 'utf8'");
include_once ('simple_html_dom.php');
$html = file_get_html('http://basket-planet.com/ru/');
//find main news
$main = $html->find('div[class=mainBlock]', 0);
$items = array();
foreach ($main->find('a') as $m){
$h = file_get_html('http://www.basket-planet.com'.$m->href.'');
$article = $h->find('div[class=newsItem]');
//convert to string to be able to modify content
$a = str_get_html(implode("
", (array)$article));
if(isset($a->find('img'))){
foreach ($a->find('img') as $img){
$img->outertext = '';}} //get rid of images
if(isset($a->find('a'))){
foreach ($a->find('a') as $link){
$link->href = 'javascript:;';
$link->target = '';}} //get rid of any javascript
if(isset($a->find('iframe'))){
foreach ($a->find ('iframe') as $frame){
$frame->outertext = '';}} //get rid of iframes
@$a->find('object', 0)->outertext = '';
@$a->find('object', 1)->outertext = '';
//modify some more to retrieve only text content
//put entire content into a div (will if statements work here???)
$text_content = '<div>'.$a.'<br>'.
($a->find('object', 0)->data > 0 ? '<a target="_blank" href="'.$a->find('object', 0)->data.'">Play Video</a> ')
($a->find('object', 1)->data > 0 ? '<a target="_blank" href="'.$a->find('object', 1)->data.'">Play Video</a> ')
($a->find('iframe[src*=youtube]', 0)->src > 0 ? '<a target="_blank" href="'.$a->find('iframe', 0)->src.'">Play Video</a> ')
//couple more checks to see if video links are present
.'</div>';
$items[] = '("'.$m->plaintext.'","'.$m->href.'","'.$text_content.'")';
}
//reverse the array so the latest items have the last id
$reverse = array_reverse($items);
$stmt = $mysqli->prepare ("INSERT IGNORE INTO test_news (article, link, text_cont) VALUES (?,?,?)");
$stmt->bind_param ???; //(implode(',', $reverse));
$stmt->execute();
$stmt->close();
?>
So the logic is for every href of an article found, I'm passing it to parse the content and I'm trying to add it to the array. I probably have a ton of errors but I can't test it yet because I don't know how to bind it to see if it works. And I'm also not sure if I can do the if statements inside $text_content div...meaning to display "Play Video" if they exist. So please, if someone can take time to work on this with me I would really appreciate it.
UPDATE: changed the if statements to comparison operators in $text_content div.
解決方案 This is exactly the scenario where mysqli is really awkward. To bind multiple params, you have to pass them all as a variable-length argument list to mysql->bind_param(), but the tricky part is that you have to bind them by reference. References in PHP can be pretty confusing.
Here's an rough example (though I have not tested this exact code):
$stmt = $mysqli->prepare("INSERT IGNORE INTO test_news
(article, link, text_cont) VALUES (?,?,?)");
foreach ($reverse as &$value) {
$params[] = &$value;
}
array_unshift(str_repeat('s', count($params)));
call_user_func_array(array($stmt, 'bind_param'), $params);
I find it much easier to use PDO when I want to write a general-purpose function to bind parameters to SQL. No binding is necessary, just pass an array of values to the PDOStatement::execute() method.
$stmt = $pdo->prepare("INSERT IGNORE INTO test_news
(article, link, text_cont) VALUES (?,?,?)");
$stmt->execute($reverse);
Update: if you need $items to contain multiple rows of data, I'd do it this way:
First, when building $items, make it an array of arrays, instead of concatenating the values together:
foreach ($main->find('a') as $m){
$items[] = array($m->plaintext, $m->href, $text_content);
}
Then prepare an INSERT statement that inserts one row, and loop over $items executing the prepared statement once for each tuple:
$stmt = $pdo->prepare("INSERT INTO test_news
(article, link, text_cont) VALUES (?,?,?)");
foreach ($items as $tuple) {
$stmt->execute($tuple);
}
I don't know why you were using array_reverse() at all, and I don't know why you were using INSERT IGNORE, so I left those out.
這篇關于如何將任意數量的值綁定到 mysqli 中的準備好的語句?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!
【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!