2

I'm trying to filter my html with DOMCrawler, but I need to break if result is found.

Is it possible to break from each?
Or how can I get $node->text(); if I use foreach? Or it's not possible?

HTML:

<table cellspacing="0" cellpadding="0" align="Center" rules="all" border="1">
    <tbody>
    <tr>
        <td>Entity Name</td>
        <td>NV Business ID</td>
        <td>Status</td>
        <td>Type</td>
    </tr>
    <tr>
        <td><a href="">GOOGLE</a></td>
        <td><a href=""></a></td>
        <td><a href="">Expired</a></td>
        <td><a href="">Reserved Name</a></td>
    </tr>
    <tr>
        <td><a href="">GOOGLE INC.</a></td>
        <td><a href="">NV20161275322</a></td>
        <td><a href="">Active</a></td>
        <td><a href="">Foreign Corporation</a>
        </td>
    </tr>
    </tbody>
</table>

PHP:

$client = new Client();
$client->setHeader('User-Agent', "Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12.388 Version/12.15");
$crawler = $client->request('GET', 'http://nvsos.gov/sosentitysearch/');
$form = $crawler->selectButton('Search')->form();
$crawler = $client->submit($form, array(
    'ctl00$MainContent$txtSearchBox' => 'google',
));
if($this->available == false)return;
$crawler->filter('table tr')->each(function (\Symfony\Component\DomCrawler\Crawler $element) {
    $status = $element->filter('td')->eq(2)->text();
    echo $status;
    if ($status == 'Active') {
        $this->available = false;
        break;
    }
});

I want to get status. And then if status is equal "Active", I want to break loop.


Ok, now I came up with something.

$crawler = $crawler->filter('#ctl00_MainContent_objSearchGrid_dgCorpSearchResults');
foreach ($crawler as $i => $content) {
    $crawler = new Crawler($content);
    foreach ($crawler->filter('#ctl00_MainContent_objSearchGrid_dgCorpSearchResults') as $node) {
        $longStatus = $node->nodeValue;
        echo $longStatus;
    }
}

But now I don't know how to get just third <td> in <tr>.

x00
  • 13,643
  • 3
  • 16
  • 40

1 Answers1

4

While you can not break from $crawler->each(), and of course you can not use break to exit a function, and there is nothing you can return so that $crawler->each() will stop iterating, but you still have a couple of options.

  1. Exceptions!
    It's always an option to exit from most of functions.
  2. foreach
    As you got it yourself, you can switch from $crawler->each() to foreach. But it's simpler than you think. Just replace
    $crawler->each(function($element) {
       your_code();
    });
    
    with
    foreach($crawler as $content) {
        $element = new Crawler($content);
        your_code();
    }
    
    No need to change anything in your code. And your original code becomes
    ...
    foreach($crawler->filter('table tr') as $content) {
        $element = new Crawler($content);
        $status = $element->filter('td')->eq(2)->text();
        echo $status;
        if ($status == 'Active') {
            $this->available = false;
            break;
        }
     }
    
    And you still can get third <td> in <tr> the same way
Skeletor
  • 3,201
  • 4
  • 30
  • 51
x00
  • 13,643
  • 3
  • 16
  • 40
  • I had to use your foreach method to call `$client->click(...)` inside the loop. With the `$crawler->each()` my PHP script failed when I tried a new request inside the loop. Thank you! – cuka Oct 08 '21 at 14:11