这是我正在运行的代码。
基本上,我收集数据,并将它们放入简单的POCO类中。在循环结束时,我想将$newItem
对象添加到$parsedItems
数组中。我是PHP的新手,这可能是一个范围界定问题吗?
<h1>Scraper Noticias</h1>
<?php
include('simple_html_dom.php');
class News {
var $image;
var $fechanoticia;
var $title;
var $description;
var $sourceurl;
function get_image( ) {
return $this->image;
}
function set_image ($new_image) {
$this->image = $new_image;
}
function get_fechanoticia( ) {
return $this->fechanoticia;
}
function set_fechanoticia ($new_fechanoticia) {
$this->fechanoticia = $new_fechanoticia;
}
function get_title( ) {
return $this->title;
}
function set_title ($new_title) {
$this->title = $new_title;
}
function get_description( ) {
return $this->description;
}
function set_description ($new_description) {
$this->description = $new_description;
}
function get_sourceurl( ) {
return $this->sourceurl;
}
function set_sourceurl ($new_sourceurl) {
$this->sourceurl = $new_sourceurl;
}
}
// Create DOM from URL or file
$initialPage = file_get_html('http://www.uvm.cl/noticias_mas.shtml');
// Declare variable to hold all parsed news items.
$parsedNews = array();
// Since the University blog page has 262 pages, we'll iterate through that.
for ($i = 2; $i <= 5; $i++) {
$url = "http://www.uvm.cl/noticias_mas.shtml?AA_SL_Session=34499aef1fc7a296fb666dcc7b9d8d05&scrl=1&scr_scr_Go=" . $i;
$page = file_get_html($url);
parse_page_for_news($page);
}
echo "<h1>Final Count:" . count($parsedNews) . "</h1>";
// Function receives an HTML Dom object, and the library works against that single HTML object.
function parse_page_for_news ($page) {
foreach($page->find('#cont2 p') as $element) {
$newItem = new News;
// Parse the news item's thumbnail image.
foreach ($element->find('img') as $image) {
$newItem->set_image($image->src);
//echo $newItem->get_image() . "<br />";
}
// Parse the news item's post date.
foreach ($element->find('span.fechanoticia') as $fecha) {
$newItem->set_fechanoticia($fecha->innertext);
//echo $newItem->get_fechanoticia() . "<br />";
}
// Parse the news item's title.
foreach ($element->find('a') as $title) {
$newItem->set_title($title->innertext);
//echo $newItem->get_title() . "<br />";
}
// Parse the news item's source URL link.
foreach ($element->find('a') as $sourceurl) {
$newItem->set_sourceurl("http://www.uvm.cl/" . $sourceurl->href);
}
// Parse the news items' description text.
foreach ($element->find('a') as $link) {
$link->outertext = '';
}
foreach ($element->find('span') as $link) {
$link->outertext = '';
}
foreach ($element->find('img') as $link) {
$link->outertext = '';
}
$newItem->set_description($element->innertext);
// Add the newly formed NewsItem to the $parsedNews object.
$parsedNews[] = $newItem;
print_r($newItem);
echo "<br /><br /><br />";
}
}
?>
在我目前对该语言的理解中,既然$parsedItems
对象是在函数之外声明的,难道不应该正确地添加它吗?
为什么我的count()调用会返回0,就好像其中没有对象一样?
这确实是一个范围界定问题。这将不起作用:
$foo= array();
function bar()
{
$foo[] = 'baz';
}
bar();
var_dump($foo); // will output an empty array
你想做的是:
$parsedNews = array();
// loop through the items as you are doing now
for ($i = 2; $i <= 5; $i++) {
$url = "http://www.uvm.cl/noticias_mas.shtml?AA_SL_Session=34499aef1fc7a296fb666dcc7b9d8d05&scrl=1&scr_scr_Go=" . $i;
$page = file_get_html($url);
$newItems = parse_page_for_news($page);
$parsedNews = array_merge($parsedNews, $newItems);
}
并有parse_page_for_news
函数在循环结束后返回parsedNews
:
return $parsedNews;
请永远不要使用global
关键字,除非你有充分的理由,否则请不要通过引用。
否。您误解了可变范围的概念。
考虑以下内容:
$foo = "bar";
function change_foo($new_foo) {
$foo = $new_foo;
}
change_foo("New Foo!");
echo $foo;
在这种情况下,输出仍然是"bar"
。这是因为change_foo()
内部的$foo
包含在函数作用域内部。
然而,如果我们要这样做(正确的方式):
$foo = "bar";
function change_foo($new_foo) {
$foo = $new_foo;
return $foo;
}
$foo = change_foo("New Foo!");
echo $foo;
结果实际上是New Foo!
。
另一种(不太推荐)的方法是:
$foo = "bar";
function change_foo(&$old_foo, $new_foo) {
$old_foo = $new_foo;
}
change_foo($foo, "New Foo!");
echo $foo;
不推荐这样做的原因是,从代码中看,$foo
并没有被更改(当然,由于我给函数起了一个恰当的名称,这似乎足够明显)。
最糟糕的方法是将$foo
移动到全局状态。
$foo = "bar";
function change_foo($new_foo) {
global $foo;
$foo = $new_foo;
}
change_foo("New Foo!");
echo $foo;
通过全球化$foo
变量,函数中的任何人都可以访问和更改它。如果函数的名称不那么明显,我们根本不可能知道它会更改$foo
的值!
在我目前对该语言的理解中,由于$parsedItems对象是在函数之外声明的,难道不应该正确添加它吗?
不需要,您需要将它传递到函数中,就像C#一样。
尽管您可以添加
global $parsedNews
在函数声明中。如果您需要修改项并使修改后的值反映在全局范围中,我认为通过引用将项传递给函数是更好的编码实践。所以你可以简单地将你的功能签名更改为这个
function parse_page_for_news ($page, &$parsedNews)
您的News
对象没有括号。它应该是一个构造函数,如下所示:
$newItem = new News();
此外,News
类需要一个构造函数。我不确定如果不声明一个,它是否会自动得到一个默认的构造函数(也就是说,没有任何参数)