Я использую три разных способа предотвращения уязвимости моего веб-приложения для SQL-инъекции.
mysql_real_escape_string()
, которое является предопределенной функцией в PHP , и этот код добавляет обратную косую черту к следующим символам: \x00
, \n
, \r
, \
, '
, "
и \x1a
. Передайте входные значения в качестве параметров, чтобы свести к минимуму вероятность внедрения SQL. Надеюсь, это поможет вам.
Рассмотрим следующий запрос:
$iId = mysql_real_escape_string("1 OR 1=1");
$sSql = "SELECT * FROM table WHERE id = $iId";
mysql_real_escape_string () здесь не защитит. Если вы используете одиночные кавычки ('') вокруг ваших переменных внутри вашего запроса, это то, что защищает вас от этого. Ниже приведено ниже решение:
$iId = (int) mysql_real_escape_string("1 OR 1=1");
$sSql = "SELECT * FROM table WHERE id = $iId";
В этом вопросе есть хорошие ответы.
Я предлагаю , наилучшим вариантом является использование PDO.
Изменить:
mysql_real_escape_string()
устарел с PHP 5.5.0. Используйте либо mysqli, либо PDO.
Альтернативой mysql_real_escape_string () является
string mysqli_real_escape_string ( mysqli $link , string $escapestr )
Пример:
$iId = $mysqli->real_escape_string("1 OR 1=1");
$mysqli->query("SELECT * FROM table WHERE id = $iId");
Единственные размерные массивы с нижней границей 0 являются другим типом или к многомерному или к не0 массивов нижней границы в IL (vector
по сравнению с array
IIRC). vector
более просто работать с - для получения до элемента x, Вы просто делаете pointer + size * x
. Для array
, необходимо сделать pointer + size * (x-lower bound)
для единственного размерного массива и все же большего количества арифметики для каждого размера, который Вы добавляете.
В основном CLR оптимизирован для значительно более общего падежа.
Массив ограничивает проверку?
массив единственного размера имеет участника длины, к которому Вы получаете доступ непосредственно - когда скомпилировано это - просто чтение памяти.
многомерный массив требует GetLength (международный размер) вызов метода, который обрабатывает аргумент для получения соответствующей длины для того размера. Это не компилирует вниз в чтение памяти, таким образом, Вы получаете вызов метода, и т.д.
, Кроме того, что GetLength (международный размер) сделает граничную проверку на параметре.
, поскольку многомерный массив является просто синтаксическим сахаром, как это - действительно просто плоская антенная решетка с некоторым индексным волшебством вычисления. С другой стороны, зубчатый массив похож, массив массивов. С двухмерной антенной решеткой, получая доступ к элементу требует чтения памяти только однажды, в то время как с двумя уровнями неровно оборвал массив, необходимо считать память дважды.
РЕДАКТИРОВАНИЕ: , По-видимому, исходный плакат перепутанные "зубчатые массивы" с "многомерными массивами", таким образом, мое обоснование точно не стоит. Для настоящей причины проверьте тяжелый ответ артиллерии Jon Skeet выше.
Зубчатые массивы являются массивами ссылок класса (другие массивы) вплоть до листового массива, который может быть массивом типа примитива. Следовательно память, выделенная для каждого из других массивов, может быть повсеместно.
принимая во внимание, что mutli-размерному массиву выделили его память в одной contigeous глыбе.
Я думаю, что это имеет что-то, чтобы сделать для факта, что зубчатые массивы являются на самом деле массивами массивов следовательно существует два уровня абстракции для получения до фактических данных.
Я со всеми остальными здесь
, у меня была программа с трехмерным массивом, позвольте мне сказать Вам, что, когда я переместил массив в два размера, я видел огромное повышение, и затем я переместился в один массив размера.
В конце, я думаю, что видел более чем 500%-е повышение производительности во время выполнения.
только недостаток был сложностью, добавленной для обнаружения, где был что в одномерном массиве, по сравнению с три один.
Я думаю многомерный, медленнее, время выполнения должно проверить два или больше (трехмерный и) граничная проверка.
Проверка границ. Ваша "j" переменная могла превысить l2, обеспеченный "i", были меньше, чем l1. Это не было бы законно во втором примере
Интересно, что я запустил следующий код сверху используя VS2008 NET3.5SP1 Win32 на коробке Vista, а в выпуске / оптимизации разница была едва заметной, в то время как debug / noopt многотомные массивы были намного медленнее. (Я провел три теста дважды, чтобы уменьшить влияние JIT на второй набор.)
Here are my numbers:
sum took 00:00:04.3356535
sum took 00:00:04.1957663
sum took 00:00:04.5523050
sum took 00:00:04.0183060
sum took 00:00:04.1785843
sum took 00:00:04.4933085
Посмотрите на второй набор из трех чисел. Разницы недостаточно для меня, чтобы кодировать все в одномерных массивах.
Хотя я их не публиковал, в Debug / unoptimized multidimension vs. одиночный / зубчатый действительно имеет огромное значение.
Полная программа:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
namespace single_dimension_vs_multidimension
{
class Program
{
public static double sum(double[] d, int l1) { // assuming the array is rectangular
double sum = 0;
int l2 = d.Length / l1;
for (int i = 0; i < l1; ++i)
for (int j = 0; j < l2; ++j)
sum += d[i * l2 + j];
return sum;
}
public static double sum(double[,] d)
{
double sum = 0;
int l1 = d.GetLength(0);
int l2 = d.GetLength(1);
for (int i = 0; i < l1; ++i)
for (int j = 0; j < l2; ++j)
sum += d[i, j];
return sum;
}
public static double sum(double[][] d)
{
double sum = 0;
for (int i = 0; i < d.Length; ++i)
for (int j = 0; j < d[i].Length; ++j)
sum += d[i][j];
return sum;
}
public static void TestTime<T, TR>(Func<T, TR> action, T obj, int iterations)
{
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < iterations; ++i)
action(obj);
Console.WriteLine(action.Method.Name + " took " + stopwatch.Elapsed);
}
public static void TestTime<T1, T2, TR>(Func<T1, T2, TR> action, T1 obj1, T2 obj2, int iterations)
{
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < iterations; ++i)
action(obj1, obj2);
Console.WriteLine(action.Method.Name + " took " + stopwatch.Elapsed);
}
public static void Main() {
Random random = new Random();
const int l1 = 1024, l2 = 1024;
double[ ] d1 = new double[l1 * l2];
double[,] d2 = new double[l1 , l2];
double[][] d3 = new double[l1][];
for (int i = 0; i < l1; ++i)
{
d3[i] = new double[l2];
for (int j = 0; j < l2; ++j)
d3[i][j] = d2[i, j] = d1[i * l2 + j] = random.NextDouble();
}
const int iterations = 1000;
TestTime<double[], int, double>(sum, d1, l1, iterations);
TestTime<double[,], double>(sum, d2, iterations);
TestTime<double[][], double>(sum, d3, iterations);
TestTime<double[], int, double>(sum, d1, l1, iterations);
TestTime<double[,], double>(sum, d2, iterations);
TestTime<double[][], double>(sum, d3, iterations);
}
}
}