0

これら 2 つのコードの断片が yii で安全かどうか教えてください。フラグメント 1:

 $numberOfRows = $this->updateAll(array('full_path' => $target, 'title' => $name,                'machine_name' => $name), 'full_path = :path', array(':path' => $path));

このクエリで $target と $name をエスケープする必要がありますか?

フラグメント 2:

$sql = "UPDATE folders";
$sql .= " SET full_path = CONCAT('" . $target . "',SUBSTR(full_path, " . (strlen($path)  + 1) . ", LENGTH(full_path)-1))";
$sql .= " WHERE full_path LIKE '" . $path . "%'";
$command = $this->dbConnection->createCommand($sql);
$command->execute();

ここで、CDbConnection::quoteValue() を使用して $target と full_path をエスケープするか、これら 2 つのフラグメントでこのようなものを使用する必要がありますか? また、Fragment 2 でパスをエスケープして、LIKE (%, _) で使用される特殊記号の問題を回避する方法も 1 つ説明します。

バインドとエスケープ %_ を使用してフラグメント 2 に変更を加えました。

$sql = "UPDATE folders";
$sql .= " SET full_path = CONCAT(:target, SUBSTR(full_path, " . (strlen($path) + 1) . ", LENGTH(full_path)-1))";
$sql .= " WHERE full_path LIKE  :pathFilter";
$command = $this->dbConnection->createCommand($sql);

//escape %_ that can be used in SQL LIKE expression
$pathFilter = addcslashes($path, '%_') . '%';

$command->bindParam(":pathFilter", $pathFilter, PDO::PARAM_STR);
$command->bindParam(":target", $target, PDO::PARAM_STR);

$command->execute();

それが正しいか?それを行うよりエレガントな方法はありますか?

4

2 に答える 2

0

よりエレガントな方法について言えば、名前付きパラメーターをいつでも回避できます。これにより、コードが大幅に短縮されます。

$sql  = "UPDATE folders SET";
$sql .= " full_path = CONCAT(?, SUBSTR(full_path, ?, LENGTH(full_path)-1))";
$sql .= " WHERE full_path LIKE ?";

//escape %,_ and \ that can be used in SQL LIKE expression
$pathFilter = addcslashes($path, '\%_') . '%'; // I've added a slash here

$command = $this->dbConnection->createCommand($sql);
$command->execute([$target, strlen($path) + 1, $pathFilter]);
于 2013-10-07T14:05:49.197 に答える
0

次の 2 つのオプションがあります。

a)モデルオブジェクトを使用します。たとえば、あなたの場合、フォルダテーブルのモデルクラスと、データを挿入/更新するその他の関連テーブルを持つことができます。これは、一連のモデルを操作するのに役立ちます (それがあなたに合っている場合)。モデル クラスには、データベースに挿入する前にデータを検証する組み込み関数があります。例: CActiveRecord 保存メソッド。関連するセキュリティの詳細については、こちらをお読みください。

使用すると、Folderモデルがあるとしましょう:

 $path='path to be updated';
 $criteria=new CDbCriteria;
  $criteria->compare('full_path',$path,true);
  $folder=Folder::model()->find($criteria);
  if($folder){
   $folder->attributes=$data;
    if($folder->save()){
      echo 'updated successfully';
    }else{
      echo 'invalid data';
    }
  }

b) モデル クラスの作成が望ましくない場合は、バインディング パラメーターの 詳細の記事を使用します。#5 バインディング パラメーターを参照してください。

$full_path および $path 変数を構築すると仮定すると、

  //$full_path=[construct using php]
  //$path=[construct using php]
  $sql = "UPDATE folders SET full_path = :newPath  WHERE full_path LIKE :oldPath"
  $command = $this->dbConnection->createCommand($sql);
  $command->bindParam(":newPath", $full_path, PDO::PARAM_STR);
  $old_path=addcslashes($path,'%_').'%'; 
  $command->bindParam(":oldPath", $old_path, PDO::PARAM_STR);
  $command->execute();

これが役立つことを願っています

于 2013-10-07T17:14:24.667 に答える