Влияние производительности использования aop

Используйте подготовленные операторы и параметризованные запросы. Это операторы SQL, которые отправляются и анализируются сервером базы данных отдельно от любых параметров. Таким образом, злоумышленник не может внедрить вредоносный SQL.

У вас в основном есть два варианта:

  1. Использование PDO (для любой поддерживаемый драйвер базы данных):
    $stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
    
    $stmt->execute(array('name' => $name));
    
    foreach ($stmt as $row) {
        // do something with $row
    }
    
  2. Использование MySQLi (для MySQL):
    $stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
    $stmt->bind_param('s', $name); // 's' specifies the variable type => 'string'
    
    $stmt->execute();
    
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) {
        // do something with $row
    }
    

Если вы подключаетесь к база данных, отличная от MySQL, есть вторая опция, зависящая от драйвера, к которой вы можете обратиться (например, pg_prepare() и pg_execute() для PostgreSQL). PDO является универсальной опцией.

Правильная настройка соединения

Обратите внимание, что при использовании PDO для доступа к базе данных MySQL real подготовленные операторы не используются по умолчанию. Чтобы исправить это, вы должны отключить эмуляцию подготовленных операторов. Пример создания соединения с использованием PDO:

$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');

$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

В приведенном выше примере режим ошибки не является строго необходимым, но рекомендуется добавить его. Таким образом, сценарий не остановится с Fatal Error, когда что-то пойдет не так. И это дает разработчику шанс catch получить любую ошибку (ы), которые являются throw n как PDOException s.

Однако обязательной является первая setAttribute() строка, которая сообщает PDO об отключении эмулируемых подготовленных операторов и использует подготовленные операторы real . Это гарантирует, что оператор и значения не будут разбираться с PHP перед отправкой на сервер MySQL (предоставление возможности злоумышленнику возможности внедрить вредоносный SQL).

Хотя вы можете установить charset в варианты конструктора, важно отметить, что «более старые» версии PHP (& lt; 5.3.6) молча игнорировали параметр charset в DSN.

Объяснение

Случается, что оператор SQL, который вы передаете prepare, анализируется и компилируется сервером базы данных. Указав параметры (либо ?, либо именованный параметр, такой как :name в примере выше), вы указываете механизм базы данных, в который вы хотите включить фильтр. Затем, когда вы вызываете execute, подготовленный оператор объединяется со значениями параметров, которые вы указываете.

Важно то, что значения параметров объединены с компилируемым оператором, а не с строкой SQL. SQL-инъекция работает, обманывая сценарий, включая вредоносные строки, когда он создает SQL для отправки в базу данных. Поэтому, отправляя фактический SQL отдельно от параметров, вы ограничиваете риск того, что закончите то, чего не намеревались. Любые параметры, которые вы отправляете при использовании подготовленного оператора, будут обрабатываться только как строки (хотя механизм базы данных может сделать некоторую оптимизацию, поэтому, конечно, параметры могут также оказаться как числа). В приведенном выше примере, если переменная $name содержит 'Sarah'; DELETE FROM employees, результатом будет просто поиск строки "'Sarah'; DELETE FROM employees", и вы не получите пустую таблицу .

Еще одно преимущество использования подготовленных операторов состоит в том, что если вы выполняете один и тот же оператор много раз в одном сеансе, он будет анализироваться и компилироваться один раз, давая вам некоторую прибыль от скорости.

О, и поскольку вы спросили, как это сделать для вставки, вот пример (с использованием PDO):

$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array('column' => $unsafeValue));

Могут ли подготовленные операторы использоваться для динамических запросов?

Пока вы все еще можете использовать подготовленные операторы для параметров запроса, сама структура самого динамического запроса не может быть параметризована, и некоторые функции запроса не могут быть параметризованы.

Для этих конкретных сценариев лучше всего использовать фильтр белого списка, который ограничивает возможные значения.

// Value whitelist
// $dir can only be 'DESC' otherwise it will be 'ASC'
if (empty($dir) || $dir !== 'DESC') {
   $dir = 'ASC';
}

40
задан cb4 19 June 2019 в 22:36
поделиться

5 ответов

Пока Вы имеете контроль из Вашего AOP, я думаю, что это эффективно. У нас действительно были проблемы производительности так или иначе, таким образом, собственным обоснованием мы не полностью осознали ситуацию ;) Это было главным образом, потому что важно, чтобы любой, который пишет аспекты, имел полный понимание весь другой аспекты в системе и как они находятся во взаимосвязи. Если Вы начинаете делать "умные" вещи, можно перехитрить себя в один миг. При выполнении умных вещей в крупном проекте с большим количеством людей, которые только видят, мелкие детали системы могут быть очень опасны мудрый производительностью. Этот совет, вероятно, применяется без AOP также, но AOP позволяет Вам выстрелить себе в ногу некоторыми реальными изящными способами.

Spring также использует проксирование для объема-manipluations и thats область, где легко получить нежелательные потери производительности.

, Но, учитывая, что Вы имеете контроль, единственная реальная болевая точка с AOP является эффектом на отладку.

33
ответ дан krosenvold 27 November 2019 в 01:27
поделиться

Если производительность будет беспокойством, мы привыкли AspectJ для большого эффекта.

, поскольку это использует переплетение байт-кода (время компиляции по сравнению со временем выполнения имеет вполне значение) это - одна из самых быстрых платформ AOP там. См.: Сравнительные тесты AOP

27
ответ дан Nathan 27 November 2019 в 01:27
поделиться

Когда я использовал его, я не сделал - но затем мое приложение не является Вашим приложением.

, Если Вы используете его для вызовов, которые используются в очень жестком цикле, существует возможность для значительного хита производительности. Если это просто используется для проверки безопасности однажды на запрос и кэш различные вещи, я не вижу, как это, вероятно, будет значительно - но вот почему необходимо представить и сравнить Ваш приложение.

я понимаю, что "мерой с Вашим приложением", вероятно, не является ответ, который Вы искали, но это может быть то, которое Вы предположили, что доберетесь :)

19
ответ дан Jon Skeet 27 November 2019 в 01:27
поделиться

При использовании основанного на прокси AOP Вы говорите приблизительно 1 дополнительный вызов метода Java на примененный аспект. Влияние производительности там довольно незначительно. Единственное реальное беспокойство является созданием прокси, но это обычно происходит только однажды на запуске приложения. Блог SpringSource имеет большое сообщение на этом:

http://blog.springsource.com/2007/07/19/debunking-myths-proxies-impact-performance/

6
ответ дан cliff.meyers 27 November 2019 в 01:27
поделиться

я использовал пружинный AOP в пакетной обработке в моем текущем проекте к транзакции, управляют базой данных.

Сначала, это было изображено, что не будет проблемы производительности, но мы не полагали в уравнение, что назвали базу данных тысячами времен. один вызов аспекта в aop не влияет на производительность очень, но умножает это на тысячи, и оказывается, что новая система была хуже, чем старая, из-за этих дополнительных вызовов метода.

я сказал бы, что aop является большой системой для использования, но пытаться обратить внимание на том, сколько вызовов методов добавляется к приложению

0
ответ дан Qix 27 November 2019 в 01:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: