将对象添加到数组,显示计数为0

时间:2012-07-27 18:49:10

标签: php arrays scope

这是我正在运行的代码。

基本上我抓取数据,并将它们放入简单的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,就好像它没有对象一样?

5 个答案:

答案 0 :(得分:5)

这确实是一个范围问题。这不起作用:

$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关键字,除非您有充分的理由,否则请不要通过引用传递。

答案 1 :(得分:3)

没有。你误解了 Variable Scope 的概念。

请考虑以下事项:

$foo = "bar";

function change_foo($new_foo) {
    $foo = $new_foo;
}

change_foo("New Foo!");
echo $foo;

在这种情况下,输出仍然是"bar"。这是因为$foo内的change_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的值!

答案 2 :(得分:2)

  

在我目前对语言的理解中,由于$ parsedItems对象是在函数之外声明的,不应该正确添加它吗?

不,你需要将它传递给函数,就像使用C#一样。

答案 3 :(得分:0)

虽然你可以添加

global $parsedNews

在你的函数声明中。如果你需要能够修改它并将修改后的值反映在全局范围内,我认为更好的编码实践是通过引用将项传递给函数。所以你可以简单地将你的功能签名改为

function parse_page_for_news ($page, &$parsedNews)

答案 4 :(得分:-6)

您的News对象没有括号。它应该是一个构造函数,如下所示:

$newItem = new News();

此外,您的News类需要构造函数。我不确定如果不通过声明,它会自动给出一个默认构造函数(即没有任何参数)