1

My project is in cakePHP but I think this is an aspect of native PHP that I am misunderstanding..

I have an afterFind($results, $primary = false) callback method in my AppModel. On one particular find if I debug($results); I get an array like this

array(
    'id' => '2',
    'price' => '79.00',
    'setup_time' => '5',
    'cleanup_time' => '10',
    'duration' => '60',
    'capacity' => '1',
    'discontinued' => false,
    'service_category_id' => '11'
)

In my afterFind I have some code like this:

foreach($results as &$model) {
  // if multiple models
  if(isset($model[$this->name][0])) {
    ....

The results of the find are from my Service model so inserting that for $this->name and checking if(isset($model['Service'][0])) should return false but it returns true? if(isset($model['Service'])) returns false as expected.

I am getting the following PHP warning:

Illegal string offset 'Service'

so what's going on here? why does if(isset($model['Service'][0])) return true if if(isset($model['Service'])) returns false?

UPDATE:

I still don't know the answer to my original question but I got around it by first checking if $results is a multidimensional array with

if(count($results) != count($results, COUNT_RECURSIVE))

Devin Crossman
  • 7,454
  • 11
  • 64
  • 102
  • Look at this answer: http://stackoverflow.com/a/16264301/577470 Also: http://stackoverflow.com/questions/9869150/illegal-string-offset-warning-php – rodrigoio Sep 11 '13 at 19:26

2 Answers2

1

Use array_key_exists() or empty() instead of isset(). PHP caches old array values strangely. They have to be manually unset using unset()

isset() does not return TRUE for array keys that correspond to a NULL value, while array_key_exists() does.

XaxD
  • 1,429
  • 14
  • 27
0

String offsets provide a mechanism to use strings as if they were an array of characters:

$string = 'abcde';
echo $string[2]; // c

$model is indeed a string for all keys except discontinued.

As for the isset($model['Service'][0]) return value, I'm a bit surprised. This is a simplified test case:

$model = '2';
var_dump(isset($model['Service'])); // bool(false)
var_dump(isset($model['Service'][0])); // bool(true)

There must be a reason somewhere. Will have a dig..

George Brighton
  • 5,131
  • 9
  • 27
  • 36
  • What's happening here is that 'Service' is invalid as a string index. If you have warnings turned on, you'll get "PHP Warning: Illegal string offset 'Service'... However, aside from the warning PHP will happily try do do something. So it converts the invalid index to 0. $model['Service'] returns '2'. Therefore $model['Service'][0] is also '2'. See the link roliveira provides above for details. – Michael Johnson Sep 12 '13 at 04:41