如何在php中为数组设置索引值为0?

I am working on my php to fetch the data to store them in an array. I have got a problem with the index value in the array, because the index value will start with 1 then it will count it up to 2, 3, 4...etc which it should start with 0 then 1, 2 3...etc, because I am using $i = 0; to start with zero as default.

Here is what I use that the index value start with 1:

if(isset($structure->parts) && count($structure->parts)) {

    for($i = 0; $i < count($structure->parts); $i++) {

        if (($structure->parts[$i]->ifdisposition) && ($structure->parts[$i]->disposition == 'attachment')) {

            foreach($structure->parts[$i]->parameters as $object) {
                if(strtolower($object->attribute) == 'name') {
                    $attachments[$i]['is_attachment'] = true;
                    $attachments[$i]['name'] = $object->value;
                    $attachments[$i]['attachment'] = '';
                }
            }
        }
    }

I have tried to change from $i++ to $i and I tried to put $i++ in the for loop, but it didn't work.

Output:

Array ( [1] => Array ( [is_attachment] => 1 [name] => 2019-01-23 (1).rar [attachment] => ) [2] => Array ( [is_attachment] => 1 [name] => email.zip [attachment] => ) )

It should be:

Array ( [0] => Array ( [is_attachment] => 1 [name] => 2019-01-23 (1).rar [attachment] => ) [1] => Array ( [is_attachment] => 1 [name] => email.zip [attachment] => ) )

Here is the full code:

<?php

require_once "Mail.php";
require_once('Mail/IMAPv2.php');

$username = 'username';
$password = 'password';
$mailserver = '{imap.domain.com:993/imap/ssl/novalidate-cert}INBOX';
$mailbox = imap_open($mailserver, $username, $password) or die("Can't connect: " . imap_last_error());
$key = "key";
$email_number = openssl_decrypt(hex2bin('477'),'AES-128-CBC', $key);
$attach_id = $_GET['attid'];

/* get information specific to this email */
$overview = imap_fetch_overview($mailbox, $email_number, 0);

$message = imap_fetchbody($mailbox, $email_number, 2);

/* get mail structure */
$structure = imap_fetchstructure($mailbox, $email_number);
$attachments = array();
$attachment_number = 0;  

if(isset($structure->parts) && count($structure->parts)) {

    for($i = 0; $i < count($structure->parts); $i++) {

        if (($structure->parts[$i]->ifdisposition) && ($structure->parts[$i]->disposition == 'attachment')) {

            foreach($structure->parts[$i]->parameters as $object) {
                if(strtolower($object->attribute) == 'name') {
                    $attachments[$i]['is_attachment'] = true;
                    $attachments[$i]['name'] = $object->value;
                    $attachments[$i]['attachment'] = '';
                }
            }
        }
    }
    ?>

I am unable to find out why the index value have always start with 1 when it should have start with zero then 1, 2, 3 as it get counting up the value each time.

Can you please show me an example how I can start the index value with 0 as a default then count it up to 1, then 2, 3, 4, 5...etc when I am using $i++?

Thank you.

It's because $structure->parts[0] does not match $structure->parts[$i]->disposition == 'attachment' in all cases.

Only create a new item in your array when one is correct and dont use the loop counter use a simpe $arr[] contruct to create the next occurance

$attachments = array();

if(isset($structure->parts) && count($structure->parts)) {
    foreach ($structure->parts as $part) {
        if (($part->ifdisposition) && ($part->disposition == 'attachment')) {

            foreach($part->parameters as $obj) {
                if(strtolower($obj->attribute) == 'name') {

                    $t['is_attachment'] = true;
                    $t['name'] = $obj->value;
                    $t['attachment'] = '';

                    $attachments[] = $t
                }
            }
        }
    }
}

Try this

foreach($structure->parts[$i]->parameters as $object) {
            if(strtolower($object->attribute) == 'name') {
                $attachment['is_attachment'] = true;
                $attachment['name'] = $object->value;
                $attachment['attachment'] = '';
                $attachments[]=$attachment;

            }
        }

If you want to know why indexes of array start with 1 and not 0, show us definition of array. But you can also loop array with unknown keys with for loop by getting array keys with PHP array_keys function

$this->arr = [1 => 'one', 2 => 'two', 3 => 'three'];
    $keys = array_keys($this->arr);
    for($i = 0; $i < count($keys); $i++) {
        $value = $this->arr[$keys[$i]];
        echo 'val: ' .$value.'<br>';
    }

Or you can wrap two foreaches into another

foreach($structure->parts as $key => $part){

        $part->ifdisposition = true;
        $part->disposition = 'attachment';
        if (($part->ifdisposition) && ($part->disposition == 'attachment')) {

            foreach($part->parameters as $object) {
                if(strtolower($object->attribute) == 'name') {
                    $attachments[$key]['is_attachment'] = true;
                    $attachments[$key]['name'] = $object->value;
                    $attachments[$key]['attachment'] = '';
                }
            }
        }
    }

Another option is to remap keys of array, using array_map but you array will be altered, so if you need the original array, you can cache it into another variable.

Here:

$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
$attachments[$i]['attachment'] = '';

You are setting the key to $i, so the first element in $structure->parts to match the criteria is the second element in the loop. To set the $attachments array starting at zero, you simply need to let PHP create the keys itself:

$attachments[] = ['is_attachment' => true, 'name' => $object->value, 'attachment' => ''];