Что касается основного вопроса в этом потоке, другие сообщения дали понять, почему мы не можем привязывать значения к именам столбцов при подготовке операторов, так что вот одно из решений:
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));
Вышеуказанное это просто пример, поэтому, разумеется, copy-> paste не будет работать. Отрегулируйте для ваших потребностей. Теперь это может не обеспечить 100% -ную защиту, но позволяет контролировать имена столбцов, когда они «входят» как динамические строки и могут быть изменены в конце пользователя. Кроме того, нет необходимости создавать какой-либо массив с именами и типами столбцов таблицы, поскольку они извлекаются из information_schema.
При создании Сделать проекта под CDT, можно просто использовать любимую оболочку и выполниться, делают во всех директорах проектов
Мы делаем это в нашей существующей сборке.
Помещенный make-файл во все Ваши внешние ссылки и Ваш проект верхнего уровня. В Вашем "всем" правиле имейте выполненный: заставьте-C./externalref1 сделать,-C./externalref2 и т.д.
мы на самом деле определяем внешние зависимости в переменной: EXT_DEP = externalref1 externalref2 тогда использует subst (замена), команда для начинаний весь подделает использование корректного вызова.
Сборка без головы с конструктором управления в настоящее время не поддерживается, см. ошибка 186847 - Внутренний компоновщик CDT не поддерживает автоматическую сборку из командной строки .
Эта функция была добавлена в CDT 6 (финальная сборка выйдет 15 июня 2009 г.). Вы можете загрузить окончательный вариант-кандидат со страницы сборок: download.eclipse.org/tools/cdt/builds/6.0.0/.
. Используя выпуск Eclipse 3.5 + CDT 6, вы можете импортировать, собирать и чистить проекты и рабочее пространство, используя следующие параметры, отправленные в Eclipse из командной строки:
eclipse -nosplash
-application org.eclipse.cdt.managedbuilder.core.headlessbuild
-import {[uri:/]/path/to/project}
-build {project_name | all}
-cleanBuild {projec_name | all}
В Windows используйте eclipsec.exe
вместо eclipse.exe
, чтобы вывод сборки записывался в стандартный вывод / stderr и так, чтобы вызов блокировался до завершения.
Переключатель « -application » указывает Eclipse запускать автономный компоновщик CDT, а не запускать рабочую среду. Остальные переключатели можно использовать по отдельности или вместе. Это означает, что вы можете проверить проект с помощью собственного сценария оболочки, « -импортировать » его в рабочую область и « -собрать » с помощью автономного построителя Managedbuilder.
] Используйте переключатель ' -data ', чтобы указать используемую рабочую область, которая может быть пустым временным каталогом; другие переключатели, поддерживаемые средой выполнения платформы, см. В документации среды выполнения: help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/misc/runtime-options.html
См. ошибка 186847, комментарий 24 и далее, чтобы получить более подробную информацию о подтвержденных функциях.
До CDT 6 вы могли использовать JDT AptBuilder (например, включенный в классический Eclipse).
Это позволяет вам создать уже настроенное рабочее пространство. Итак, вы: проверяете свой источник, настраиваете рабочую область, которая указывает на проверенные проекты. Затем ваши сценарии автоматической сборки могут обновлять проверки и запускать AptBuilder без необходимости запуска графического интерфейса.