20260
POSTした値をセッションに追加して配列にしています。  
POSTした値と同じ[key]があったときは上書きしたいのですが、何度やってもうまく行きません。  
どのようにしたら上書きするでしょうか。

```

    session_start();
    
    //セッション変数「item」が未設定の場合は空の配列に初期化
    if (!isset($_SESSION['item'])) {
        $_SESSION['item'][] = array();
    } else if (is_string($_SESSION['item'])) {
        //セッション変数「cart」に文字列が存在していれば配列セッションcartを代入
        $_SESSION['item'][] = array($_SESSION['item']);
    }
    sort($_SESSION['item']);
    
    /********************追加処理**********************/
    
    $key = isset($_SESSION['item'][ $_POST['key'] ]);
    
    //セッション変数内にPOSTで送られてきたidと同じものが無かった場合の処理
        if ($key) {
            if (isset($_SESSION['item']['type'])) {
                $_SESSION['item']['type'] = $_POST['type'];
    
                if (isset($_SESSION['item']['days'])) {
                    $_SESSION['item']['days'] = $_POST['days'];
    
                }
            }
        }else{
            if (isset($_POST['key'])) {
                if (isset($_POST['type'])) {
                    if (isset($_POST['day'])) {
                        if (isset($_POST['price'])) {
                            if (isset($_POST['days'])) {
                                //送られてきたデータを配列に格納
                                $item = array('key'    => $_POST['key'],
                                              'type'   => $_POST['type'],
                                              'day' => $_POST['day'],
                                              'price'  => $_POST['price'],
                                              'days'     => $_POST['days']);
                            }
                        }
                    }
                }
            } else {
                echo = 'no item';   //何もカートに入っていません
            }
        }
    //セッション変数「item」に配列の中身を追加
    if (isset($item)) {
        $_SESSION['item'][] = $item;
    };
    
    $item = $_SESSION['item'];
    $item = array_filter($item);
    
```

セッションは配列にして受渡ししています。  
$item = $_SESSION['item']

```

    Array ( 
    [1] => Array ( [key] => 1450669337 [type] => 4 [dayset] => 20151225 [price]=> 1,000 [days] => 1 )
    [2] => Array ( [key] => 1450669517 [type] => 6 [dayset] => 20151231 [price] => 3,000 [days] => 3 ) )
    
```
CC BY-SA 3.0
2015-12-21T08:43:24.030
20253
2015-12-25T01:29:47.773
2015-12-21T10:17:00.567
13755
13755
question
php
セッション配列が上書きできない
> セッションは配列にして受渡ししています。  
>  $item = $_SESSION['item']

との事ですが、PHPでは基本的に値渡しとなるため、$item 変数を用いての操作の場合、元の配列（$_SESSION）は更新されません。

マニュアルにも、以下の様な記述があります。

> <http://php.net/manual/ja/language.operators.assignment.php>  
>  代入は、元の変数を新しい変数にコピーする(値による代入)ため、 片方の変数に対する変更はもう片方に影響を与えないということに 注意してください。

これは以下の様なコードを実行してみると挙動が分かるかと思います。

```

    <?php
    
    $origin = array(1 => array('a' => 1));
    $test = $origin[1];
    $test['a'] = 0; // <--
    
    print_r($test);
    /*
    Array
    (
        [a] => 0 // <-- 変更されている
    )
    */
    
    print_r($origin);
    /*
    Array
    (
        [1] => Array
            (
                [a] => 1 // <-- 変更されていない
            )
    )
    */
    
```

元の配列を変更したい場合、リファレンス渡しという方法で代入することで解決するかと思います。  
リファレンス渡しについての詳細はPHPマニュアルを参考してください。  
<http://php.net/manual/ja/language.references.whatdo.php>

以下に、簡単な例を記載します。

```

    <?php
    
    $origin = array(1 => array('a' => 1));
    $test =& $origin[1]; // & を使ってリファレンス渡しする
    $test['a'] = 0; // <--
    
    print_r($test);
    /*
    Array
    (
        [a] => 0 // <-- 変更されている
    )
    */
    
    print_r($origin);
    /*
    Array
    (
        [1] => Array
            (
                [a] => 0 // <-- 変更されている
            )
    )
    */
    
```
CC BY-SA 3.0
2015-12-21T10:15:52.470
20255
2015-12-25T01:29:47.773
2015-12-25T01:29:47.773
2944
2944
20253
answer
```

    $_SESSION = array(
        'item' => array(
            array('key' => 1450669337, 'type' => 4, 'dayset' => 20151225, ...),
            array('key' => 1450669317, 'type' => 6, 'dayset' => 20151231, ...),
            ...
        )
    );
    
```

という構造を期待されていて、上記 `key` が `$_POST['key']` に対応するものとして回答します。

まず、

```

    $key = isset($_SESSION['item'][ $_POST['key'] ]); //NG
    
```

前述の構造において `145069337` は配列の **値** ですから、 `$_SESSION['item']['145069337']`
といった形でアクセスすることはできず、順番に `key === 145069337` となる要素を探す必要があります。

```

        if (isset($_SESSION['item']['type'])) { //NG
            $_SESSION['item']['type'] = $_POST['type']; //NG
    
```

ここでは item の直下に type があるものとして書かれていますが、正しくは、 item の中の **n番目の要素の中に** type
が存在する、という構造ですよね？

それを踏まえて、現状の構造を維持する場合は次のようになるでしょう。

```

    $found = false; //見つかったかどうか
    
    foreach ($_SESSION['item'] as $index => $item) {
        if ($item['key'] === $_POST['key']) {
            // とりあえず$itemだけ更新して、
            $item['type'] = $_POST['type'];
            $item['days'] = $_POST['days'];
            // $_SESSIONに書き戻す
            $_SESSION['item'][$index] = $item;
            // 見つけたというフラグを立ててループを抜ける
            $found = true;
            break;
        }
    }
    
    if(!$found) {
        // 見つからなかったので追加する
        $_SESSION['item'][] = ...;
    }
    
```

もしくは、`$_SESSION['item'][] = $item` の代わりに `$_SESSION['item'][$item['key']] =
$item` として、key を配列のキーにしてしまえば、検索する必要はなくなります。

この場合の `$_SESSION` は以下のような構造になります。実装例は省略。

```

    $_SESSION = array(
        'item' => array(
            1450669337 => array('key' => 1450669337, 'type' => 4, 'dayset' => 20151225, ...),
            1450669317 => array('key' => 1450669317, 'type' => 6, 'dayset' => 20151231, ...),
            ...
        )
    );
    
```
CC BY-SA 3.0
2015-12-21T11:38:04.200
20260
2015-12-21T11:38:04.200
8000
20253
answer