GAV GAV - 17 days ago 7
PHP Question

function (Crawler $node) symfony issue with using values

The below code with get the a url, web contents (the helper isn't here but basic cURL with Guzzle) the uses Dom crawler to find content on page like link or contents in side tags. Because the crawler Function (Crawler $node) looping through, it being function means I can't use values for created for a new JsonResponse or in anyway outside that function and returns
The controller must return a response (null given). Did you forget to add a return statement somewhere in your controller?



namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;


class DefaultController extends Controller
{

public $use;
public $item;
public $price;
public $link;
public $code;

/**
* @Route("/", name="homepage")
*/

public function indexAction()
{


$html = $this->container->get('webscraper.helper')->contents('url');

$crawler = new Crawler($html['html']);

$crawler->filter('div.product')->each(function (Crawler $node) {

$item = $node->filter('h3')->text();

$price = $node->filter('p')->text();

$link = $node->filterXPath("//a/@href")->text();

$secondpage = $this->container->get('webscraper.helper')->contents($link);

// echo $secondpage['size'];

$crawler2 = new Crawler($secondpage['html']);

$description = $crawler2->filterXPath("//div[@class='productText']")->text();
// echo $size;


$use[] = array('title' => $item,'size' =>'5' ,'unit_price' => $price,'description' => $description);


});
// because of above }); cannot access $use
return new JsonResponse($use);


}


}

Answer

To access variable inside Closure function you need to "import" it by adding use (&$results) see my snippet below

$results = [];

$crawler->filter(self::RESULT_SELECTOR)->each(function (Crawler $node) use (&$results) {
    // code here
}

return new JsonResponse($results);

For primitive types you need to force reference by prepending with & for objects it's enough to just pass variable name