0

Why is this array count returning 1 instead of 2?

Shouldn't it return 2?

$join = [
   'JOIN' => ['coins','users.id','user_id'],
   'JOIN' => ['coins','users.id','user_id']
];

echo count($join);
13
  • 12
    Because you have only one unique key Commented Aug 10, 2016 at 17:53
  • There is $join['JOIN'] as the only outer key in the array. you have set two, but the second immediately overwrites the first. Commented Aug 10, 2016 at 17:55
  • @Nosyara, how may I modify this array to have 2 keys, without changing the key name? Commented Aug 10, 2016 at 17:55
  • @Nosyara is right. You're overwriting the same key. Try using var_dump(); first next time. it becomes obvious 3v4l.org/40XCL Commented Aug 10, 2016 at 17:56
  • 1
    This seems like an XY problem. Maybe if you explain why you are trying to do this, we could help you find a better solution? Commented Aug 10, 2016 at 17:58

4 Answers 4

3

You are creating an associative array, which means that each element is associated to one unique key. Therefore, in an array, each key can only appear once. A key appearing twice means that the value will be overwritten.

If you try to var_dump your array, it would have this output:

array(1) {
  ["JOIN"]=>
  array(3) {
    [0]=>
    string(5) "coins"
    [1]=>
    string(8) "users.id"
    [2]=>
    string(7) "user_id"
  }
}

As seen from this result, only one line exists.

If you need to have 'JOIN' in every element, maybe you want to change your array structure into this:

$join = [
   ['JOIN' => ['coins','users.id','user_id']],
   ['JOIN' => ['coins','users.id','user_id']]
];

This will carry the information 'JOIN' in every element. However, I cannot imagine why you would need such a thing.

Instead, maybe you want to have multiple elements under the 'JOIN key:

$join = [
    'JOIN' => [
        ['coins','users.id','user_id'],
        ['coins','users.id','user_id']
    ]
];

As per your comments, maybe you eventually want to have a structure like this:

$join = [
    'JOIN' => [
        ['coins','users.id','user_id'],
        ['coins','users.id','user_id'],
    ],
    'INNER JOIN' => [
        ['coins','users.id','user_id'],
        ['coins','users.id','user_id'],
    ]
];

According to your comments, it might be more desirable if you do this through object-oriented programming instead:

class Join{
    const JOIN = 0;
    const INNER_JOIN = 1;
    // we are using constants to prevent bugs caused by typos
    public $type;
    public $coins;
    public $usersDotId; // I don't really know what you are trying to do here
    public $userId;
}

Then you can use it like this:

$joins = [];

$join = new Join();
$join->type = Join::INNER_JOIN;
$join->coins = "some_value";
$join->usersDotId = "some_value";
$join->userId = "some_value";
$joins[] = $id;
Sign up to request clarification or add additional context in comments.

Comments

2
$join = [
   'JOIN' => ['coins','users.id','user_id'],
   'JOIN' => ['coins','users.id','user_id']
];

echo count($join);

how may I modify this array to have 2 keys, without changing the key name?

In order to not need to change this key name, make JOIN an array of numeric values so structurally you want:

array:

 ----> [Join] :
          \---> [0] 
                 \--->   coins
                 |--->   users.id
                 |--->   user.id

This can be achieved with this syntax (clarified for understanding):

$join = [
   'JOIN' => [0] => ['coins','users.id','user_id'],
             [1] => ['coins','users.id','user_id']
];

(simplified for ease):

$join = [
       'JOIN' =>  ['coins','users.id','user_id'],
                  ['coins','users.id','user_id']
    ];

gives you a $join array with a count of 1, which contains (the one) an array with a count of 2, each of those containing 3 elements.

Comments

2

Without addressing the more specific problem that appeared in the comments, and acknowledging that you've already accepted an answer that works for your purposes, here is a more theoretical explanation for why you can't have two of the same key. This may be not be useful for you, but hopefully it could help someone who does not intuitively grasp this concept.

Regardless of whether you assign your own string keys ($array = ['key' => 'value'];), assign your own integer keys ($array = [42 => 'the answer'];), or let PHP automatically assign integer keys ($array[] = 'something';), the keys must be unique.

According to the PHP manual for arrays:

An array in PHP is actually an ordered map. A map is a type that associates values to keys.

Most programming languages have something like this. This association of values to keys means that by definition, keys must be unique. If a language allowed you to create a "map" with multiple identical keys pointing to different values, looking up a value by key would be impossible (or at least would produce ambiguous results), so the map would be fairly useless.

PHP will let you write things like:

$example = [
   'a' => 1,
   'b' => 2,
   'a' => 3,
];
var_dump($example);

without giving any errors, but the result of that will be:

array (size=2)
  'a' => int 3
  'b' => int 2

where 'a' => 3 has overwritten the previously defined value of the 'a' key. This allows the map to continue to work, so that $example['a'] will always yield the same value. If you actually could have

array (size=3)
  'a' => int 1
  'b' => int 2
  'a' => int 3

Then what would be the result of $example['a']? Any defined behavior (first instance of 'a', etc.) would mean that some values of 'a' would be inaccessible.

Comments

0

Because you are using same array key to both the element

try this,

<?php
$join = [
   'JOIN1' => ['coins','users.id','user_id'],
   'JOIN2' => ['coins','users.id','user_id']
];
echo count($join);
?>

Or with same key try following

$join = [
   ['JOIN' => ['coins','users.id','user_id']],
   ['JOIN' => ['coins','users.id','user_id']]
];

1 Comment

I see what you want to do through JOIN1 and JOIN2, that you are implying they should be different keys. But judging on what @William wants to do in this example, it seems the rule that "If you are string + numbers in your array keys you are most likely doing something wrong" applies here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.