এই থ্রেডের মূল প্রশ্ন হিসাবে, অন্যান্য পোস্টগুলি স্পষ্ট জানিয়ে দিয়েছে যে বিবৃতি প্রস্তুত করার সময় আমরা কলামের নামগুলিতে কেন মানগুলি আবদ্ধ করতে পারি না, তাই এখানে একটি সমাধান রয়েছে:
class myPdo{
private $user = 'dbuser';
private $pass = 'dbpass';
private $host = 'dbhost';
private $db = 'dbname';
private $pdo;
private $dbInfo;
public function __construct($type){
$this->pdo = new PDO('mysql:host='.$this->host.';dbname='.$this->db.';charset=utf8',$this->user,$this->pass);
if(isset($type)){
//when class is called upon, it stores column names and column types from the table of you choice in $this->dbInfo;
$stmt = "select distinct column_name,column_type from information_schema.columns where table_name='sometable';";
$stmt = $this->pdo->prepare($stmt);//not really necessary since this stmt doesn't contain any dynamic values;
$stmt->execute();
$this->dbInfo = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
public function pdo_param($col){
$param_type = PDO::PARAM_STR;
foreach($this->dbInfo as $k => $arr){
if($arr['column_name'] == $col){
if(strstr($arr['column_type'],'int')){
$param_type = PDO::PARAM_INT;
break;
}
}
}//for testing purposes i only used INT and VARCHAR column types. Adjust to your needs...
return $param_type;
}
public function columnIsAllowed($col){
$colisAllowed = false;
foreach($this->dbInfo as $k => $arr){
if($arr['column_name'] === $col){
$colisAllowed = true;
break;
}
}
return $colisAllowed;
}
public function q($data){
//$data is received by post as a JSON object and looks like this
//{"data":{"column_a":"value","column_b":"value","column_c":"value"},"get":"column_x"}
$data = json_decode($data,TRUE);
$continue = true;
foreach($data['data'] as $column_name => $value){
if(!$this->columnIsAllowed($column_name)){
$continue = false;
//means that someone possibly messed with the post and tried to get data from a column that does not exist in the current table, or the column name is a sql injection string and so on...
break;
}
}
//since $data['get'] is also a column, check if its allowed as well
if(isset($data['get']) && !$this->columnIsAllowed($data['get'])){
$continue = false;
}
if(!$continue){
exit('possible injection attempt');
}
//continue with the rest of the func, as you normally would
$stmt = "SELECT DISTINCT ".$data['get']." from sometable WHERE ";
foreach($data['data'] as $k => $v){
$stmt .= $k.' LIKE :'.$k.'_val AND ';
}
$stmt = substr($stmt,0,-5)." order by ".$data['get'];
//$stmt should look like this
//SELECT DISTINCT column_x from sometable WHERE column_a LIKE :column_a_val AND column_b LIKE :column_b_val AND column_c LIKE :column_c_val order by column_x
$stmt = $this->pdo->prepare($stmt);
//obviously now i have to bindValue()
foreach($data['data'] as $k => $v){
$stmt->bindValue(':'.$k.'_val','%'.$v.'%',$this->pdo_param($k));
//setting PDO::PARAM... type based on column_type from $this->dbInfo
}
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);//or whatever
}
}
$pdo = new myPdo('anything');//anything so that isset() evaluates to TRUE.
var_dump($pdo->q($some_json_object_as_described_above));
উপরেরটি কেবল একটি উদাহরণ, তাই বলা বাহুল্য, অনুলিপি-> পেস্ট কাজ করবে না। আপনার প্রয়োজনের জন্য সামঞ্জস্য করুন। এখন এটি 100% সুরক্ষা সরবরাহ করতে পারে না, তবে এটি কলামের নামগুলিতে কিছু নিয়ন্ত্রণের অনুমতি দেয় যখন তারা ডায়নামিক স্ট্রিং হিসাবে "আসে" এবং ব্যবহারকারীদের শেষে পরিবর্তন হতে পারে। তদ্ব্যতীত, আপনার টেবিল কলামের নাম এবং প্রকারগুলি যেহেতু তথ্য_সেমিমা থেকে বের করা হয়েছে সেগুলি নিয়ে কিছু অ্যারে তৈরি করার দরকার নেই।
array('u'=>'users', 't'=>'table', 'n'=>'nonsensitive_data')
) এর সাথে সম্পর্কিত এমন