diff --git a/docs/guide-ja/db-active-record.md b/docs/guide-ja/db-active-record.md index 75ced594a3..0b9cefb64e 100644 --- a/docs/guide-ja/db-active-record.md +++ b/docs/guide-ja/db-active-record.md @@ -859,6 +859,8 @@ class Order extends ActiveRecord 続けて書く、ということです。ご覧のように、`customer_id` は `Order` のプロパティであり、 `id` は`Customer` のプロパティです。 +> Warning: リレーション名としては `relation` は予約済みで使えません。これを使うと `ArgumentCountError` となります。 + ### リレーショナル・データにアクセスする diff --git a/docs/guide-ja/db-migrations.md b/docs/guide-ja/db-migrations.md index 76cdf9d38b..ca850633ee 100644 --- a/docs/guide-ja/db-migrations.md +++ b/docs/guide-ja/db-migrations.md @@ -187,6 +187,22 @@ class m150101_185401_create_news_table extends Migration カラムの型を定義するために利用できる全てのメソッドのリストは、[[yii\db\SchemaBuilderTrait]] の API ドキュメントで参照することが出来ます。 +> Info: 生成されるファイルのパーミッションと所有者は現在の環境によって決定されます。 + これが原因でファイルにアクセス出来ない場合が生じ得ます。例えば、docker コンテナ内で作成されたマイグレーションのファイルをホストで編集するとそうなる場合があります。 + このような場合には MigrateController の `newFileMode` および/または `newFileOwnership` を変更することが出来ます。 + 例えば、アプリケーション設定で次のように設定します。 + ```php + [ + 'migrate' => [ + 'class' => 'yii\console\controllers\MigrateController', + 'newFileOwnership' => '1000:1000', # Default WSL user id + 'newFileMode' => 0660, + ], + ], + ]; + ``` ## マイグレーションを生成する diff --git a/docs/guide-ja/db-query-builder.md b/docs/guide-ja/db-query-builder.md index 02221ea1ed..e779ba7a52 100644 --- a/docs/guide-ja/db-query-builder.md +++ b/docs/guide-ja/db-query-builder.md @@ -716,6 +716,9 @@ $query = (new \yii\db\Query()) ->all(); ``` +インデックス付けが働くためには、[[yii\db\Query::indexBy()|indexBy()]] メソッドに渡されるカラム名が結果セットに存在する必要があります。 +そのことを保証するのは開発者の責任です。 + 式の値によってインデックスするためには、[[yii\db\Query::indexBy()|indexBy()]] メソッドに無名関数を渡します。 ```php diff --git a/docs/guide-ja/helper-json.md b/docs/guide-ja/helper-json.md new file mode 100644 index 0000000000..d3224447e8 --- /dev/null +++ b/docs/guide-ja/helper-json.md @@ -0,0 +1,26 @@ +Json wp +=========== + +Json wp JSON GR[hуfR[hA̐ÓI\bh񋟂܂B +`[[yii\helpers\Json::encode()]]` \bh̓GR[hEG[܂A + `[[yii\web\JsExpression]]` IuWFNǧ`ŕ\ꂽ JavaScript ̎̓GR[h܂B +ł̓GR[h `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE` ̃IvVōs܂B +ڍׂɂ‚Ă [PHP:json_encode](https://secure.php.net/manual/ja/function.json-encode.php) QƂĉB + +## `o + +ł `[[yii\helpers\Json::encode()]]` \bh͐`ĂȂ JSON (Ȃ킿󔒖̂) o͂܂B +lԂɂƂēǂ݂₷̂ɂ邽߂ɁAu`o pretty printingv ON ɂ邱Ƃo܂B + +> Note: `o͂͊J̃fobOɂ͖𗧂‚ł傤Ai‹ł͐܂B + +CX^XƂɐ`o͂Lɂ邽߂ɂ̓IvVw肷邱Ƃo܂BȂ킿 : + +```php +$data = ['a' => 1, 'b' => 2]; +$json = yii\helpers\Json::encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); +``` +JSON wp̐`o͂O[oɗLɂ邱Ƃo܂BႦ΁Aݒt@C index.php ̒ : +```php +yii\helpers\Json::$prettyPrint = YII_DEBUG; // fobOE[hł͐`o͂gp +``` diff --git a/docs/guide-ja/helper-overview.md b/docs/guide-ja/helper-overview.md index 9ae4e7df99..5e0818acde 100644 --- a/docs/guide-ja/helper-overview.md +++ b/docs/guide-ja/helper-overview.md @@ -33,7 +33,7 @@ echo Html::encode('Test > test'); - HtmlPurifier - Imagine (yii2-imagine エクステンションによって提供) - Inflector -- Json +- [Json](helper-json.md) - Markdown - StringHelper - [Url ヘルパ](helper-url.md) diff --git a/docs/guide-ja/runtime-sessions-cookies.md b/docs/guide-ja/runtime-sessions-cookies.md index 1a5cf03f53..d9a836d23f 100644 --- a/docs/guide-ja/runtime-sessions-cookies.md +++ b/docs/guide-ja/runtime-sessions-cookies.md @@ -403,3 +403,4 @@ Yii 2.0.21 以降、[[yii\web\Cookie::sameSite]] 設定がサポートされて [PHP マニュアル](https://www.php.net/manual/ja/session.security.ini.php) で示されているように、`php.ini` にはセッションのセキュリティに関する重要な設定があります。 推奨される設定を必ず適用して下さい。特に、PHP インストールのデフォルトでは有効にされていない `session.use_strict_mode` を有効にして下さい。 +この設定は [[yii\web\Session::useStrictMode]] を使って設定することも出来ます。 diff --git a/docs/guide-ja/security-authentication.md b/docs/guide-ja/security-authentication.md index bb20efe823..40ecc722b1 100644 --- a/docs/guide-ja/security-authentication.md +++ b/docs/guide-ja/security-authentication.md @@ -42,15 +42,16 @@ return [ 指定されたアクセス・トークンを使ってユーザ識別情報クラスのインスタンスを探します。 単一の秘密のトークンでユーザを認証する必要がある場合 (ステートレスな RESTful アプリケーションなどの場合) に、このメソッドが使用されます。 * [[yii\web\IdentityInterface::getId()|getId()]]: ユーザ識別情報クラスのインスタンスによって表されるユーザの ID を返します。 -* [[yii\web\IdentityInterface::getAuthKey()|getAuthKey()]]: クッキー・ベースのログインを検証するのに使用されるキーを返します。 - このキーがログイン・クッキーに保存され、後でサーバ・サイドのキーと比較されて、 - ログイン・クッキーが有効であることが確認されます。 +* [[yii\web\IdentityInterface::getAuthKey()|getAuthKey()]]: 自動ログインが有効にされている場合に、 + セッションと自動ログインを検証するキーを返します。 * [[yii\web\IdentityInterface::validateAuthKey()|validateAuthKey()]]: クッキー・ベースのログイン・キーを検証するロジックを実装します。 特定のメソッドが必要でない場合は、中身を空にして実装しても構いません。例えば、あなたのアプリケーションが純粋なステート・レス RESTful アプリケーションであるなら、 実装する必要があるのは [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]] と [[yii\web\IdentityInterface::getId()|getId()]] だけであり、他のメソッドは全て中身を空にしておくことが出来ます。 +逆にあなたのアプリケーションがセッションのみの認証を使用する場合は、 +[[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]] 以外の全てのメソッドを実装する必要があります。 次の例では、[[yii\web\User::identityClass|ユーザ識別情報クラス]] は、`user` データベース・テーブルと関連付けられた [アクティブ・レコード](db-active-record.md) クラスとして実装されています。 @@ -99,7 +100,7 @@ class User extends ActiveRecord implements IdentityInterface } /** - * @return string 現在のユーザの認証キー + * @return string|null 現在のユーザの認証キー */ public function getAuthKey() { @@ -108,7 +109,7 @@ class User extends ActiveRecord implements IdentityInterface /** * @param string $authKey - * @return bool 認証キーが現在のユーザに対して有効か否か + * @return bool|null 認証キーが現在のユーザに対して有効か否か */ public function validateAuthKey($authKey) { @@ -117,9 +118,8 @@ class User extends ActiveRecord implements IdentityInterface } ``` -前述のように、`getAuthKey()` と `validateAuthKey()` は、 -あなたのアプリケーションがクッキー・ベースのログイン機能を使用する場合にのみ実装する必要があります。 -この場合、次のコードを使って、各ユーザに対して認証キーを生成して、`user` テーブルに保存しておくことが出来ます。 +次のコードを使って、各ユーザに対して認証キーを生成して、 +`user` テーブルに保存しておくことが出来ます。 ```php class User extends ActiveRecord implements IdentityInterface diff --git a/docs/guide-ja/security-best-practices.md b/docs/guide-ja/security-best-practices.md index 558967dc2c..24076635fe 100644 --- a/docs/guide-ja/security-best-practices.md +++ b/docs/guide-ja/security-best-practices.md @@ -353,3 +353,29 @@ return [ > Note: 「ホスト・ヘッダ攻撃」に対する保護のためには、常に、フィルタの使用よりもウェブ・サーバの構成を優先すべきです。 [[yii\filters\HostControl]] は、サーバの構成が出来ない場合にだけ使うべきものです。 + +### SSL ピア検証を構成する + +SSL 証明書検証の問題、例えば : + +``` +cURL error 60: SSL certificate problem: unable to get local issuer certificate +``` + +または + +``` +stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed +``` + +を解決する方法については、典型的な誤解があります。SSL ピア検証を無効化するよう示唆する間違った情報が数多くありますが、決して従ってはいけません。 +そんなことをすれば、マン・イン・ザ・ミドル型の攻撃を可能にします。そうするのではなく、PHP を適切に構成すべきです。 + +1. [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem) をダウンロードする。 +2. php.ini に以下を追加する。 + ``` + openssl.cafile="/path/to/cacert.pem" + curl.cainfo="/path/to/cacert.pem". + ``` + +`cacert.pem` ファイルを最新に保つ必要があることに注意して下さい。 diff --git a/docs/guide-ja/security-passwords.md b/docs/guide-ja/security-passwords.md index 45b4f0caa1..6049bd57cc 100644 --- a/docs/guide-ja/security-passwords.md +++ b/docs/guide-ja/security-passwords.md @@ -3,7 +3,7 @@ ほとんどの開発者はパスワードを平文テキストで保存してはいけないということを知っていますが、パスワードを `md5` や `sha1` でハッシュしてもまだ安全だと思っている開発者がたくさんいます。かつては、前述のハッシュ・アルゴリズムを使えば十分であった時もありましたが、 -現代のハードウェアをもってすれば、そのようなハッシュはブルート・フォース・アタックを使って非常に簡単に復元することが可能です。 +それらのハッシュや更に強力なハッシュでも、現代のハードウェアをもってすればブルート・フォース・アタックを使って非常に簡単にクラックすることが可能です。 最悪のシナリオ (アプリケーションに侵入された場合) であっても、ユーザのパスワードについて強化されたセキュリティを提供することが出来るように、 ブルート・フォース・アタックに対する耐性が強いハッシュ・アルゴリズムを使う必要があります。現在、最善の選択は `bcrypt` です。 diff --git a/docs/guide-ja/structure-models.md b/docs/guide-ja/structure-models.md index 6eb85db405..e469858faf 100644 --- a/docs/guide-ja/structure-models.md +++ b/docs/guide-ja/structure-models.md @@ -477,8 +477,8 @@ public function fields() ]; } -// いくつかのフィールドを除外する方法。親の実装を継承しつつ、公開すべきでないフィールドは -// 除外したいときに適している。 +// いくつかのフィールドを除外する方法。親の実装を継承しつつ、公開すべきでないフィールドを +// 除外したいときに最適。 public function fields() { $fields = parent::fields(); diff --git a/docs/guide-ja/test-environment-setup.md b/docs/guide-ja/test-environment-setup.md index c999bc0f66..4c62e24bfe 100644 --- a/docs/guide-ja/test-environment-setup.md +++ b/docs/guide-ja/test-environment-setup.md @@ -17,7 +17,7 @@ Yii 2 は [`Codeception`](https://github.com/Codeception/Codeception) テスト Codeception をインストールすることが出来ます。 ``` -composer require codeception/codeception -composer require codeception/specify -composer require codeception/verify +composer require --dev codeception/codeception +composer require --dev codeception/specify +composer require --dev codeception/verify ``` diff --git a/docs/guide-ja/tutorial-core-validators.md b/docs/guide-ja/tutorial-core-validators.md index 100c1c1e51..317dd43245 100644 --- a/docs/guide-ja/tutorial-core-validators.md +++ b/docs/guide-ja/tutorial-core-validators.md @@ -82,7 +82,7 @@ public function rules() このバリデータが属性を検証するのに使用されるとき、このプロパティのデフォルト値はその属性の名前に接尾辞 `_repeat` を付けた名前になります。 例えば、検証される属性が `password` であれば、このプロパティのデフォルト値は `password_repeat` となります。 -- `compareValue`: 入力値が比較される定数値。 +- `compareValue`: 入力値が比較される定数値(または値を返すクロージャ)。 このプロパティと `compareAttribute` の両方が指定された場合は、このプロパティが優先されます。 - `operator`: 比較演算子。デフォルト値は `==` で、入力値が `compareAttribute` の値または `compareValue` と等しいことを検証することを意味します。 次の演算子がサポートされています。 @@ -156,6 +156,7 @@ compare バリデータは、文字列や数値を比較するためにしか使 `timestampAttribute` を使う場合、入力値が UNIX タイムスタンプに変換されること、そして、UNIX タイムスタンプは定義により UTC であることに注意して下さい。 すなわち、[[yii\validators\DateValidator::timeZone|入力のタイム・ゾーン]] から UTC への変換が実行されます。 +(この動作は、2.0.39 以降では、[[yii\validators\DateValidator::$defaultTimeZone|$defaultTimeZone]] を設定して変更することが出来ます) - バージョン 2.0.4 以降では、タイムスタンプの [[yii\validators\DateValidator::$min|最小値]] または [[yii\validators\DateValidator::$max|最大値]] を指定することも出来ます。 @@ -191,8 +192,8 @@ compare バリデータは、文字列や数値を比較するためにしか使 このバリデータはデータを検証しません。 その代りに、検証される属性が空のときに、その属性にデフォルト値を割り当てます。 -- `value`: デフォルト値、または、デフォルト値を返す PHP コーラブル。 - 検証される属性が空のときにこのデフォルト値が割り当てられます。PHP コーラブルのシグニチャは、次のものでなければなりません。 +- `value`: デフォルト値、または、デフォルト値をコールバックとして返すクロージャ。 + 検証される属性が空のときにこの値が割り当てられます。クロージャのシグニチャは、次のものでなければなりません。 ```php function foo($model, $attribute) { @@ -270,24 +271,49 @@ function foo($model, $attribute) { ```php [ // a1 の入力値が a1 のカラムに存在する必要がある + // すなわち、a1 = 1 は、"a1" カラムに 1 の値が存在する場合に有効 ['a1', 'exist'], + // 以下と同義 + ['a1', 'exist', 'targetAttribute' => 'a1'], + ['a1', 'exist', 'targetAttribute' => ['a1' => 'a1']], // a1 の入力値が a2 のカラムに存在する必要がある + // すなわち、a1 = 2 は、"a2" カラムに 2 の値が存在する場合に有効 ['a1', 'exist', 'targetAttribute' => 'a2'], + // 以下と同義 + ['a1', 'exist', 'targetAttribute' => ['a1' => 'a2']], + + // a2 の入力値が a2 のカラムに存在する必要がある。a1 がエラー・メッセージを受ける + // すなわち、a2 = 2 は、"a2" カラムに 2 の値が存在する場合に有効 + ['a1', 'exist', 'targetAttribute' => ['a2']], + // 以下と同義 + ['a1', 'exist', 'targetAttribute' => ['a2' => 'a2']], // a1 と a2 の両方が存在する必要がある。両者はともにエラー・メッセージを受け取る + // すなわち、a1 = 3, a2 = 4 は、"a1" カラムに 3, "a2" カラムに 4 が存在する場合に有効 [['a1', 'a2'], 'exist', 'targetAttribute' => ['a1', 'a2']], + // 以下と同義 + [['a1', 'a2'], 'exist', 'targetAttribute' => ['a1' => 'a1', 'a2' => 'a2']], // a1 と a2 の両方が存在する必要がある。a1 のみがエラー・メッセージを受け取る + // すなわち、a1 = 5, a2 = 6 は、"a1" カラムに 5, "a2" カラムに 6 が存在する場合に有効 ['a1', 'exist', 'targetAttribute' => ['a1', 'a2']], + // 以下と同義 + ['a1', 'exist', 'targetAttribute' => ['a1' => 'a1', 'a2' => 'a2']], // a2 の値が a2 のカラム、a1 の値が a3 のカラムに存在する必要がある。a1 がエラー・メッセージを受け取る + // すなわち、a1 = 7, a2 = 8 は、"a3" カラムに 7, "a2" カラムに 8 が存在する場合に有効 ['a1', 'exist', 'targetAttribute' => ['a2', 'a1' => 'a3']], + // 以下と同義 + ['a1', 'exist', 'targetAttribute' => ['a2' => 'a2', 'a1' => 'a3']], // a1 が存在する必要がある。a1 が配列である場合は、その全ての要素が存在する必要がある ['a1', 'exist', 'allowArray' => true], + // すなわち、a1 = 9 は、"a1" カラムに 9 が存在する場合に有効 + // a1 = [9, 10] は、"a1" カラムに 9 と 10 が存在する場合に有効 // type_id が ProductType クラスで定義されているテーブルの id カラムに存在する必要がある + // すなわち、type_id = 1 は ProductType のテーブルの "id" カラムに 1 が存在する場合に有効 ['type_id', 'exist', 'targetClass' => ProductType::class, 'targetAttribute' => ['type_id' => 'id']], // 同上。定義済みの "type" リレーションを使用。 @@ -310,9 +336,18 @@ function foo($model, $attribute) { 複数のカラムの存在を同時に検証するために配列を使うことが出来ます。 配列の値は存在を検証するのに使用される属性であり、配列のキーは入力値が検証される属性です。 キーと値が同じ場合は、値だけを指定することが出来ます。 + 検証されるモデルが ModelA であり、検証に使用されるモデルが ModelB であるとすると、 + 下記のように `targetAttribute` を構成することが出来ます。 + - `null` => ModelA の現在検証されている属性の値が ModelB の同名の属性の保存されている値に対してチェックされる + - `'a'` => ModelA の現在検証されている属性の値が ModelB の属性 "a" の保存されている値に対してチェックされる + - `['a']` => ModelA の属性 "a" の値が ModelB の属性 "a" の保存されている値に対してチェックされる + - `['a' => 'a']` => 同上 + - `['a', 'b']` => ModelA の属性 "a" の値が ModelB の属性 "a" の保存されている値に対してチェックされ、 + 同時に、ModelA の属性 "b" の値が ModelB の属性 "b" の保存されている値に対してチェックされる + - `['a' => 'b']` => ModelA の属性 "a" の値が ModelB の属性 "b" の保存されている値に対してチェックされる +- `targetRelation`: バージョン 2.0.14 以降は簡便な `targetRelation` 属性が使えます。これは指定されたリレーションの定義によって `targetClass` と `targetAttribute` の属性をオーバーライドするものです。 - `filter`: 入力値の存在をチェックするのに使用される DB クエリに適用される追加のフィルタ。 - これには、文字列、または、追加のクエリ条件を表現する配列を使うことが出来ます - (クエリ条件の書式については、[[yii\db\Query::where()]] を参照してください)。 + これには、追加のクエリ条件を表現する文字列または配列を使うことが出来ます (クエリ条件の書式については、[[yii\db\Query::where()]] を参照してください)。 または、`function ($query)` というシグニチャを持つ無名関数でも構いません。 `$query` は関数の中で修正できる [[yii\db\Query|Query]] オブジェクトです。 - `allowArray`: 入力値が配列であることを許容するか否か。デフォルト値は `false`。 @@ -638,19 +673,34 @@ IPv4 アドレス `192.168.10.128` も、制約の前にリストされている ```php [ // a1 の入力値が a1 のカラムにおいてユニークである必要がある + // すなわち、a1 = 1 は、"a1" カラムに 1 の値が存在しない場合に有効 ['a1', 'unique'], + // 以下と同義 + ['a1', 'unique', 'targetAttribute' => 'a1'], + ['a1', 'unique', 'targetAttribute' => ['a1' => 'a1']], // a1 の入力値が a2 のカラムにおいてユニークである必要がある + // すなわち、a1 = 2 は、"a2" カラムに 2 の値が存在しない場合に有効 ['a1', 'unique', 'targetAttribute' => 'a2'], + // 以下と同義 + ['a1', 'unique', 'targetAttribute' => ['a1' => 'a2']], // a1 と a2 の両方がユニークである必要がある。両者がともにエラー・メッセージを受け取る + // すなわち、a1 = 3, a2 = 4 は、"a1" カラムに 3 の値が存在せず、同時に、"a2" カラムに 4 の値が存在しない場合に有効 [['a1', 'a2'], 'unique', 'targetAttribute' => ['a1', 'a2']], + // 以下と同義 + [['a1', 'a2'], 'unique', 'targetAttribute' => ['a1' => 'a1', 'a2' => 'a2']], // a1 と a2 の両方がユニークである必要がある。a1 のみがエラー・メッセージを受け取る ['a1', 'unique', 'targetAttribute' => ['a1', 'a2']], // a2 の値が a2 のカラム、a1 の値が a3 のカラムにおいてユニークである必要がある。a1 がエラー・メッセージを受け取る + // すなわち、a1 = 5, a2 = 6 は、"a3" カラムに 5 の値が存在せず、同時に、"a2" カラムに 6 の値が存在しない場合に有効 ['a1', 'unique', 'targetAttribute' => ['a2', 'a1' => 'a3']], + + // type_id が ProductType クラスで定義されているテーブルの "id" カラムにおいてユニークである必要がある + // すなわち、type_id = 1 は ProductType のテーブルの "id" カラムに 1 が存在しない場合に有効 + ['type_id', 'unique', 'targetClass' => ProductType::class, 'targetAttribute' => 'id'], ] ``` @@ -665,10 +715,19 @@ IPv4 アドレス `192.168.10.128` も、制約の前にリストされている 複数のカラムのユニーク性を同時に検証するために配列を使うことが出来ます。 配列の値はユニーク性を検証するのに使用される属性であり、配列のキーはその入力値が検証される属性です。 キーと値が同じ場合は、値だけを指定することが出来ます。 -- `filter`: 入力値のユニーク性をチェックするのに使用される DB クエリに適用される追加のフィルタ。 - これには、文字列、または、追加のクエリ条件を表現する配列を使うことが出来ます - (クエリ条件の書式については、[[yii\db\Query::where()]] を参照してください)。 - または、`function ($query)` というシグニチャを持つ無名関数でも構いません。`$query` は関数の中で修正できる [[yii\db\Query|Query]] オブジェクトです。 + 検証されるモデルが ModelA であり、検証に使用されるモデルが ModelB であるとすると、 + 下記のように `targetAttribute` を構成することが出来ます。 + - `null` => ModelA の現在検証されている属性の値が ModelB の同名の属性の保存されている値に対してチェックされる + - `'a'` => ModelA の現在検証されている属性の値が ModelB の属性 "a" の保存されている値に対してチェックされる + - `['a']` => ModelA の属性 "a" の値が ModelB の属性 "a" の保存されている値に対してチェックされる + - `['a' => 'a']` => 同上 + - `['a', 'b']` => ModelA の属性 "a" の値が ModelB の属性 "a" の保存されている値に対してチェックされ、 + 同時に、ModelA の属性 "b" の値が ModelB の属性 "b" の保存されている値に対してチェックされる + - `['a' => 'b']` => ModelA の属性 "a" の値が ModelB の属性 "b" の保存されている値に対してチェックされる +- `filter`: 入力値がユニークであることをチェックするのに使用される DB クエリに適用される追加のフィルタ。 + これには、追加のクエリ条件を表現する文字列または配列を使うことが出来ます (クエリ条件の書式については、[[yii\db\Query::where()]] を参照してください)。 + これは、または、`function ($query)` というシグニチャを持つ無名関数でも構いません。 + `$query` は関数の中で修正できる [[yii\db\Query|Query]] オブジェクトです。 ## [[yii\validators\UrlValidator|url]]