# RFC: Arrays starting with a negative index

- Status: Implemented (PHP 8.0)
- Authors: Pedro Magalhães, pmmaga@php.net
- Date: 2017-04-20
- Version: 0.4
- Original: https://wiki.php.net/rfc/negative_array_index
- Page: https://externals.io/rfc/negative_array_index
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Votes

### Arrays starting with a negative index for 8.0 (closed)

Yes: 17 · No: 2

Voters: ashnazg (Yes), bwoebi (Yes), daverandom (Yes), derick (Yes), diegopires (No), emir (Yes), galvao (Yes), jhdxr (Yes), kelunik (Yes), marcio (Yes), mcmic (Yes), mike (Yes), nikic (Yes), peehaa (Yes), pmmaga (Yes), salathe (No), tpunt (Yes), trowski (Yes), zimt (Yes)

### Deprecation notice for 7.3 (closed)

Yes: 8 · No: 14

Voters: ashnazg (No), bwoebi (Yes), colinodell (No), dams (Yes), daverandom (No), derick (No), diegopires (No), dmitry (No), emir (No), galvao (Yes), jhdxr (No), kelunik (Yes), marcio (Yes), mcmic (No), mike (Yes), nikic (No), peehaa (Yes), pmmaga (Yes), salathe (No), stas (No), trowski (No), zimt (No)

## Discussions on the mailing list

- [On arrays starting with a negative index](https://externals.io/message/98302.md) — started on 2017-02-15, 6 messages
- [\[RFC\] \[Discussion\] Arrays starting with a negative index](https://externals.io/message/99125.md) — started on 2017-05-21, 4 messages
- [\[RFC\] \[VOTE\] Arrays starting with a negative index](https://externals.io/message/99412.md) — started on 2017-06-06, 24 messages
- [In case your e-mail client did not start a new thread](https://externals.io/message/99415.md) — started on 2017-06-06, 1 messages
- [\[RFC\] \[VOTE\] Restarted vote on the negative arrays](https://externals.io/message/99511.md) — started on 2017-06-13, 4 messages
- [\[RFC\] \[Discussion\] Arrays starting with a negative index](https://externals.io/message/101861.md) — started on 2018-02-13, 7 messages
- [\[RFC\] \[VOTE\] Arrays starting with a negative index](https://externals.io/message/101951.md) — started on 2018-03-02, 2 messages

---

## Introduction

On the documentation for `array_fill` the `start_index` description mentions: “If `start_index` is negative, the first index of the returned array will be `start_index` and the following indices will start from zero.” This is consistent everywhere when an explicit negative key is used and implicit keys are used afterwards.

## Proposal

In other words, any array that has a number `n` as it's first numeric key will have for it's next implicit key either `n+1` if `n >= 0` or `0` if `n < 0`. This RFC proposes to make this consistent by always using `n+1` regardless of the sign of `n`.

As also mentioned on the relevant part of the [arrays documentation](http://php.net/manual/en/language.types.array.php):

> if no key is specified, the maximum of the existing integer indices is taken, and the new key will be that maximum value plus 1 (but at least 0).

This RFC proposes to eliminate the parenthesis part of that sentence. Which is an exception to a rule, that people have to learn one way or the other.

This proposal targets 8.0. However, to ease the transition and find places where this may become an issue, there is a secondary vote for emitting a deprecation notice in cases where the behavior will change.

All the variables in this code:

```php
<?php
 
$a = array_fill(-2, 3, true);
$b = [-2 => true, true, true];
$c = ["string" => true, -2 => true, true, true];
unset($c["string"]);
$d[-2] = true;
$d[] = true;
$d[] = true;
```

Result in the array:

```php
array(3) {
  [-2]=>
  bool(true)
  [0]=>
  bool(true)
  [1]=>
  bool(true)
}
```

> NOTE: If accepted, during the deprecation phase the following `E_DEPRECATED` notice would be emitted in cases where the behavior will change:
> 
> ```
> Deprecated: In the next major version of PHP the implicit keys of this array will start from -1 instead of 0 in ...
> ```

With the implementation of this RFC, they will all result in:

```php
array(3) {
  [-2]=>
  bool(true)
  [-1]=>
  bool(true)
  [0]=>
  bool(true)
}
```

## Backward Incompatible Changes

Code that relies on the current behavior to access array elements with an explicit key after that array has been started with a negative index and used implicit keys afterwards will change it's behavior. Example:

```php
<?php
 
$a[-2] = true; // Current: Key is -2, RFC: Key is -2
$a[] = true; // Current: Key is 0, RFC: Key is -1
$a[] = true; // Current: Key is 1, RFC: Key is 0
 
if ($a[1] === true) {
    echo 'Accessing key 1 explicitly';
}
```

Will no longer output `Accessing key 1 explicitly`.

> NOTE: If accepted, during the deprecation phase the `E_DEPRECATED` notice mentioned in the previous section would be emitted.

## Proposed PHP Version(s)

PHP 8.0 (Deprecation notice for 7.3)

## Unaffected PHP Functionality

Arrays with explicit keys, string keys, or an initial numeric index `>= -1` are not affected. This also means that arrays that never use explicit keys will still start with `0`.

Furthermore, iterating over arrays without explicit keys (ie. `foreach`) is not affected.

## Voting Choices

Both votes require a 2/3 majority.

**Vote: Arrays starting with a negative index for 8.0** — Yes: 17 · No: 2 (closed)

---

**Vote: Deprecation notice for 7.3** — Yes: 8 · No: 14 (closed)

> The previous vote targeting 7.2 was closed with 14 for and 16 against

## Patches and Tests

This RFC is implemented by the following patches:

1. Implementation: <https://github.com/php/php-src/pull/2383>
2. Documentation: *WIP*

## References

Version 0.3:

Discussion on the mailing list: <https://externals.io/message/98302>

First proposal Voting period discussion: <https://externals.io/message/99412>

Second proposal Voting period discussion: <https://externals.io/message/99511>

---

Version 0.4:

Discussion on the mailing list: <https://externals.io/message/101861>
