🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

2回答

1510閲覧

cakephp3 DBに保存する時はセッターを使い、取得する時にゲッターを使用したい

hagiwarasannnnn

総合スコア13

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

0クリップ

投稿2020/12/18 00:13

前提・実現したいこと

いつもお世話になっております。
cakephp3で、DBに保存する時はセッターを使い、暗号化。
取得する時はゲッターを使い複合化するプログラムを実現したいです。

発生している問題・エラーメッセージ

DBに保存する時、セッターの処理を通るのですが、その後ゲッターの処理も通過してしまいます。
セッター(暗号化) → ゲッター(複合化)の処理順になっているため、平文でDBに保存されてしまいます。
それと、確認したいのですがセッターはDBに保存する時のみ通る処理で、ゲッターはDBから取得する時のみ通る処理だと思っているのですが認識はあっているでしょうか?

該当のソースコード

UserController.php

php

1$user = $this->request->data; 2$UsersAdminTable = TableRegistry::get('UsersAdmin'); 3$userAdmin = $UsersAdminTable->newEntity(); 4$userAdmin->login_id = $user['login_id']; 5$userAdmin->password = $user['password']; 6$userAdmin->lastName = $user['lastName']; 7$userAdmin->fastName = $user['fastName']; 8$userAdmin->address = $user['address']; 9$UsersAdminTable->save($userAdmin); 10

Entity/UsersAdmin.php

php

1<?php 2 namespace App\Model\Entity; 3 4 use Cake\Auth\DefaultPasswordHasher; 5 use Cake\ORM\Entity; 6 use Cake\Core\Configure; 7 use Cake\Core\Configure\Engine\PhpConfig; 8 use Cake\Utility\Security; 9 10 class UsersAdmin extends Entity 11 { 12 protected $_accessible = [ 13 '*' => true, 14 'id' => false 15 ]; 16 17 protected function _setPassword($password) 18 { 19 if(strlen($password) > 0) 20 { 21 // パスワードをハッシュ化 22 return (new DefaultPasswordHasher)->hash($password); 23 } 24 } 25 26 protected function _setAddress($address) 27 { 28 if(strlen($address) > 0) 29 { 30 return $this->encryption($address); 31 } 32 } 33 34 protected function _getAddress($address) 35 { 36 if(strlen($address) > 0) 37 { 38 return $this->decrypt($address); 39 } 40 } 41 42 protected function _setFastName($fastname) 43 { 44 if(strlen($fastname) > 0) 45 { 46 return $this->encryption($fastname); 47 } 48 } 49 50 protected function _getFastName($fastname) 51 { 52 if(strlen($fastname) > 0) 53 { 54 return $this->decrypt($fastname); 55 } 56 } 57 58 protected function _setLastName($lastname) 59 { 60 if(strlen($lastname) > 0) 61 { 62 return $this->encryption($lastname); 63 } 64 } 65 66 protected function _getLastName($lastname) 67 { 68 if(strlen($lastname) > 0) 69 { 70 return $this->decrypt($lastname); 71 } 72 } 73 74 protected function _setFastKanaName($fastname) 75 { 76 if(strlen($fastname) > 0) 77 { 78 return $this->encryption($fastname); 79 } 80 } 81 82 protected function _getFastKanaName($fastname) 83 { 84 if(strlen($fastname) > 0) 85 { 86 return $this->decrypt($fastname); 87 } 88 } 89 90 protected function _setLastKanaName($fastname) 91 { 92 if(strlen($fastname) > 0) 93 { 94 return $this->encryption($fastname); 95 } 96 } 97 98 protected function _getLastKanaName($fastname) 99 { 100 if(strlen($fastname) > 0) 101 { 102 return $this->decrypt($fastname); 103 } 104 } 105 106 // 暗号化 107 public function encryption($enc_name=null) 108 { 109 $key = Configure::read('key','encryption'); 110 $salt = Configure::read('salt','encryption'); 111 return bin2hex(openssl_encrypt($enc_name,'aes-256-ecb',$key)); 112 } 113 114 // 複合化 115 public function decrypt($decname=null) 116 { 117 $key = Configure::read('key','encryption'); 118 $salt = Configure::read('salt','encryption'); 119 // 複合可能か16進数チェック 120 if (ctype_xdigit($decname) && strlen($decname) % 2 == 0) { 121 $decname = hex2bin($decname); 122 return openssl_decrypt($decname,'aes-256-ecb',$key); 123 } 124 else{ 125 return ''; 126 } 127 128 return $decname; 129 } 130 131} 132 133?> 134 135

補足情報(FW/ツールのバージョンなど)

cakephp3.7

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

アクセサーメソッド(ゲッター)は、エンティティを保存する際にも使用されます。

このメソッドは唯一の引数として _properties 配列内にある基本の値を受け取ります。 アクセサーはエンティティーを保存する際に使われますので、データをフォーマットするメソッド を定義する場合は注意が必要です。データはフォーマットされた状態で保存されることになります。

https://book.cakephp.org/3.next/ja/orm/entities.html#id5

仮想プロパティを使ってみてはいかがでしょうか?

php

1protected function _getDecryptedAddress() 2 { 3 if(strlen($this->_properties['address']) > 0) 4 { 5 return $this->_properties['address']; 6 } 7 }

アクセスするときは

php

1$userAdmin->decrypted_address

https://book.cakephp.org/3.next/ja/orm/entities.html#entities-virtual-properties

投稿2020/12/18 05:12

azukiazusa

総合スコア112

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hagiwarasannnnn

2020/12/21 05:51

返信遅れてしまい申し訳ございません。 >アクセサーメソッド(ゲッター)は、エンティティを保存する際にも使用されます。 ご解説までいただきありがとうございます! 仮想プロパティを使用し、呼び出す際はアクセスするやり方で実装しました。
guest

0

このようなユースケースでは、エンティティのgetter/setterではなく独自のフィールド型を利用して実装するとよいです。

独自の型を作成する | データベースの基本 - 3.9

格納するデータが文字列であれば、Cake\Database\StringType を継承したクラスを作成し、toPHP, toDatabaseメソッドでそれぞれdecrypt, encryptの処理を入れてください。
対象のフィールドの型により継承する型クラスを変更して、必要なフィールドの型の分だけ暗号化のカスタムタイプクラスを用意します。

あとは、Table側で_initializeSchemaを実装して、対象のフィールドに上記で作成したカスタムタイプを設定すればよいです。

投稿2020/12/18 05:10

編集2020/12/18 05:11
nojimage

総合スコア959

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hagiwarasannnnn

2020/12/21 05:53

返信遅れてしまい申し訳ございません。azukiazusa様の案を採用させていただきました。 nojimage様の実装方法も高評価いたします。 こちらの方法で実装ができたら、ここに共有いたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問