Filtering methods in the Doctrine Result Pane?

I am very new to the Doctrine, so this may seem like a pretty obvious question for those more experienced.

I am writing a data import tool that should verify that each imported row contains valid data. For example, the line contains a link to the product code, I need to check if an existing Product object exists with this code. If not, mark this line as invalid.

Now I can easily do something similar for each row.

$productCode = $this->csv->getProductNumber(); $product = $doctrine->getRepository('MyBundle:Product')->findOneBy(array('code' => $productCode )); 

But that seems terribly ineffective. So I thought about returning the entire product collection, and then iterating through it.

 $query = $this->getEntityManager()->createQuery('SELECT p FROM MyBundle\Entity\Product p'); $products = $query->getResult(); 

All is well and good, but then I need to write messy loops for the search.

Two questions:

1). I was wondering if I lacked some useful methods, for example, in your Magento Collections, where you can search the Collection results without additional database deletions. For example, in Magento, this will iterate over the collection and filter by code property.

 $collection->getItemByColumnValue("code","FZTY444"); 

2). At the moment, I am using the query below, which returns a "rectangular array". More effective, but could be better.

 $query = $this->getEntityManager()->createQuery('SELECT p.code FROM MyBundle\Entity\Product p'); $products = $query->getResult(); 

Is there a way to return a single dimensional array without repeating the result set and converting it to a flat array, so I can use in_array () for the results?

+4
source share
2 answers

If I understand your question correctly, you want to filter the array of objects returned by getResult (). I had a similar question, and I think I figured out two ways to do this.

Method 1: Arrays

Use the array_filter method for your $products variable. Yes, this corresponds to a “loop” in the background, but I think this is a generally acceptable way of filtering arrays, not recording. You need to provide a callback (an anonymous function in 5.3 is preferred). Here is an example

 $codes = array_filter($products, function($i) { if ($i->getCode() == '1234') { return true; } return false; }); 

Basically in your function, return true if you want the result to be returned in $codes and false otherwise (not sure if false is mandatory, or if void is a valid value).

Method 2: Doctrine ArrayCollection

In your custom repository or the ever returned getResult () method, you can instead return an ArrayCollection. This is in the Doctrine Doctrine\Common\Collections\ namespace. A more detailed description of the interface for this method can be found here . So in this case you will have

 $query = $this->getEntityManager()->createQuery('SELECT p FROM MyBundle\Entity\Product p'); $products = new ArrayCollection($query->getResult()); 

Then you can use the filter () method to collect the array. Use it very much like array_filter. Other than this, the first argument is not required because you call it this way: $products->filter(function($i) { ... });

The ArrayCollection class is an iterator, so you can use it in foreach loops for your heart, and it should not be different from the array of your products. If your code explicitly uses $products[$x] , then it should be plug 'n' play *.

* Note. I really have not tested this code or concept, but based on everything I read seems legit. I will update my answer if it turns out that I'm wrong.

+6
source

You can use a different hydration mode. $ query-> getResult () usually returns the result of hydrating the object. Take a look at $ query-> getScalarResult (), which should be more suitable for your needs.

Learn more about the Doctrine 2 site .

0
source

All Articles