質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.78%

PHP 多次元連想配列での削除について

受付中

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 912

score 9

環境

Laravel 6.2
PHP 7.2.14

困っていること

セッション内に作った多次元連想配列でunset()が動作せず困っています。
なぜunsetが動作しないのか、また、その他実現方法ありましたら、教えていただきたいです。

対象の配列

構造(実際に動くコードではありませんが、このような形です)

session(['human_data' => [
                '山田太郎' => [
                    'firstName' => '山田',
                    'lastName' => '太郎',
                    'firstNameKana' => 'ヤマダ',
                    'lastNameKana' => 'タロウ',
                    'tall' => '168',
                    'foot' => '26.5',
                    'age' => '24',
                ],
                '山田花子' => [
                    'firstName' => '山田',
                    'lastName' => '花子',
                    'firstNameKana' => 'ヤマダ',
                    'lastNameKana' => 'ハナコ',
                    'tall' => '160',
                    'foot' => '24.5',
                    'age' => '20',
                ],
                '田中次郎' => [
                   'firstName' => '田中',
                   'lastName' => '次郎',
                   'firstNameKana' => 'タナカ',
                   'lastNameKana' => 'ジロウ',
                   'tall' => '180',
                   'foot' => '28',
                   'age' => '19',
               ]
         ]]);

求める最終的な形

"山田太郎"や"山田花子"を指定して、そのキーと配下の要素をすべて消したいです。

dd(session('human_data')[$delete_key]);
//
//OUTPUT
//
//array:4 [▼
//  "山田太郎" => array:7 [▶]
//  "田中次郎" => array:7 [▶]
//]

試したこと

削除をしようと記述したコード

$delete_key = (key(array_slice(session('human_data'),1,1,true)));
// $delete_keyの中には'山田花子'が返ってきています。
unset(session('human_data')[$delete_key]);

自分の考え

dd(session('human_data')[$delete_key]);
//
//OUTPUT
//
//array:7 [▼
//  "firstName" => "山田"
//  "lastName" => "花子"
//  "firstNameKana" => "ヤマダ"
//  "lastNameKana" => "ハナコ"
//  "tall" => "160"
//  "foot" => "24.5"
//  "stance" => "20"
//]


と返ってきているので削除したい部分はずれなく指定できているかと思います。
連想配列で子要素を持っているものは削除できないのかとも考えています。

最後に

正しい言葉をつかえているかも怪しいですが、ご教授いただけると幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2021/01/25 15:22 編集

    Laravelでなければできるのでしょうか?

    (途中で送信してしまったので追加してます)

    キャンセル

  • chichiyanagi

    2021/01/25 15:54

    お久しぶりです。コメントありがとうございます。

    laravelでセッションを操作するときはRequestクラスのメソッドを使うか、ファサードを使用するかヘルパ関数を使用するかの3パターンと認識しているのですが、`$_session`も使えるのでしょうか?
    (質問返しになってしまい申し訳ありません)

    もし新規でPHPを書きテストしたかという話であれば、申し訳ありませんが行っていません。

    キャンセル

  • m.ts10806

    2021/01/25 16:05

    Laravel限定の話かどうかで違うという点
    動かないコードを例として提示されてもそれは単に動かないコードでしかなく、そこから指摘する必要がある(自身が試したことではない)
    という点。タイトル「多次元連想配列での削除」が生PHPならできるのか?というのは「Laravelでのやり方を聞きたいのかどうか」を方向性として確立したかったため。
    いずれにしてもPHPで書かれているため"$_SESSION"に限らずスーパーグローバル変数は使えますが、Laravelの管理下から外れるかどうかを理解して使う必要はありますね。
    あとはLaravelのドキュメント確認しつつ試すしか

    キャンセル

  • chichiyanagi

    2021/01/25 16:23

    タイトルと内容に相違があり申し訳ありませんでした。
    本来のセッション内の配列をつくるコードは
    ```
    $old = session('human_data');
    if (empty(session('human_data'))) {
    session(['human_data' => [
    $fullname => [
    //代入処理
    ]
    ]]);
    } else {
    // 二件目以降の場合はマージして追加(同配列がある場合は上書き処理)
    $new = [
    $fullname => [
    //代入処理
    ]
    ];
    session(['human_data' => array_merge($old, $new)]);
    ```
    のようなものでした。ただ配列の構造を示したかったため、あのような書き方をしてしまいました。

    再び質問することになってしまうのですが、
    Controller内で'dd($_SESSION)'としても”Undefined variable: _SESSION”が返ってきます。
    こちらを追記するうえで、'session_start();'は記述していません。
    何か別の要因があるのでしょうか?
    まだあまり調べていないので、簡単なことなので自分で調べてくださいであれば自力で探します。

    キャンセル

回答 2

+1

unset(session('human_data')[$delete_key]);


↑これでは変更後が保存されてない。

//セッションから取り出す
$human_data = session('human_data');

//$human_dataを加工
unset($human_data[$delete_key]);

//再度セッションに保存
session(['human_data' => $human_data]);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/01/25 16:10

    回答ありがとうございます。

    こういったメソッドは直接配列内のデータを構うことができると勘違いしていました。
    勉強になりました。

    たしかにご教授いただいた方法で行いたいことを実装することができました。

    ありがとうございます。

    キャンセル

0

array_splice使って、指定の要素を確実に削除したらいいのでは?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/01/25 16:27

    回答ありがとうございます。

    array_spliceの使用も考えたのですが、他の処理よりも重いと見かけたことや、番号ではなく連想配列名で一意に指定することで、誤動作を防ぎたい狙いがありました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.78%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る