Yii Framework Forum: CArrayDataProvider sorting broken - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

CArrayDataProvider sorting broken Rate Topic: -----

#1 User is offline   yoshi 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 170
  • Joined: 28-February 09
  • Location:Germany

Posted 18 October 2010 - 09:30 AM

Hi,

i was playing around with CArrayDataProvider and discovered that a php error shows up when using sort functionality
Parameter 1 to array_multisort() expected to be a reference, value given


The problem is
call_user_func_array('array_multisort', $args);
inside the sortData method.

After asking the big oracle (thus: google) it doesn't seem to be a bug in yii but in php. Sorry, i ment a feature that works as designed, but the behavior changes from time to time...

To make it short: there were already some tickets/discussions going on about the behavior of call_user_func_array / array_multisort (see #49353, or #49069 or #49241 ). As mentioned there it's working as designed since PHP 5.3 (i'm running 5.3.1) and it was only possible by accident that arrays could be passed by value to array_multisort instead of by reference in PHP <= 5.2.

Therefore the yii code doesn't work, because it passes them by value. At php.net they say everythings fine now and working as designed, but to make it work i not only have to pass the arrays by reference but also the SORT_ flags... wtf? Have you ever passed such a flag by reference?

I'M TALKING TO MUCH :D
I wanted to create a ticket for this, but thought it would be useful to discuss a proper solution here. Maybe a good way to avoid using 'call_user_func_array' completly?

If you want to dive into this topic i'll make it easy so you don't have to search the original code ^^
Here it is:
	protected function sortData($directions)
	{
		if(empty($directions))
			return;
		$args=array();
		foreach($directions as $name=>$descending)
		{
			$column=array();
			foreach($this->rawData as $index=>$data)
				$column[$index]=is_object($data) ? $data->$name : $data[$name];
			$args[]=$column;
			$args[]=$descending ? SORT_DESC : SORT_ASC;
		}
		$args[]=&$this->rawData;
		call_user_func_array('array_multisort', $args);
	}


I have also done a quick fix, but it looks nasty:
	protected function sortData($directions)
	{
		if(empty($directions))
			return;
		$args=array();
		$args_collect=array(); // Long story - we are collecting every argument in a second array just because after the unset() below php would transfer the reference in $args[] into a value
		foreach($directions as $name=>$descending)
		{
			$column=array();
			foreach($this->rawData as $index=>$data)
				$column[$index]=is_object($data) ? $data->$name : $data[$name];
			$args[]=&$column;
			$args_collect[]=&$column; // Now by reference
			$sortflag=$descending ? SORT_DESC : SORT_ASC;
			$args[]=&$sortflag; // Yes sir, even the flag has to be passed by reference
			$args_collect[]=&$sortflag;
			unset($column,$sortflag); // Unset vars otherwise we'd always get the same content (because of reference)
		}
		$args[]=&$this->rawData;
		call_user_func_array('array_multisort', $args);
	}


Some thoughts on how to deal with this?

Best regards
0

#2 User is offline   Giovanni D. 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 236
  • Joined: 23-December 08
  • Location:London (UK)

Posted 23 October 2010 - 09:59 AM

Hello,
I'm having the same problem with an example I've submitted to the yii playground project; you can see the source here: http://www.yiiplaygr...w/gridViewArray

As you can see I had to comment the sort parameters or else I'd get the same error you reported ::)

bye,
Giovanni.
- Yii Playground: collaborative demo app with small examples to play with.. join us ;) [Fork on github]

- DeploYii: Yii powered task runner and deployment solution

- My Linkedin profile
0

#3 User is offline   yoshi 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 170
  • Joined: 28-February 09
  • Location:Germany

Posted 28 October 2010 - 08:17 AM

Oh, i now see that there is a ticket created already: http://code.google.c.../detail?id=1653
It's from Oct 06, 2010 - so i must have overlooked it. Sorry!

Regards

0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users