Эффективный оператор if / for loop - PullRequest
3 голосов
/ 29 марта 2012

2 коротких вопроса, основанных на попытках сделать мой код более эффективным (я думаю, что моя главная задача - сделать весь мой (довольно сложный) сайт основанным на какой-то среде MVC, но не быть профессиональным программистом, я думаю, чтобыть длинной и крутой кривой обучения ..)

  1. В этом коде есть способ объединить оператор if и цикл for, чтобы избежать вложения:

    if($fileatt['name']!=null)
    {
      $attachedFiles = "You uploaded the following file(s)\n";
      for($i=0;$i<count($docNames);$i++)
      {
        $attachedFiles = $attachedFiles. " - " . $docNames[$i] . "\n";
      }
    }
    
  2. В настоящий момент я делаю довольно стандартную вещь - разделяю свой массив $ _POST из представления формы, очищаю содержимое и сохраняю элементы в отдельных переменных:

    $name = cleanInput($_POST['name']);
    $phone = cleanInput($_POST['phone']);
    $message = cleanInput($_POST['message']);
    ...
    

(где cleanInput() содержит striptags() и mysql_real_escape_string())

Я думал, что хранение всей информации в массиве может сделать мой код более эффективным,но есть ли способ применить функцию ко всем (или выбранным) элементам массива?Например, в R это то, что делает функция apply().

В качестве альтернативы, учитывая, что все мои переменные имеют то же имя, что и в массиве $_POST, существует ли способ генерировать все переменныединамически в цикле foreach?(Я знаю, что стандартный ответ, когда люди спрашивают, могут ли они динамически генерировать переменные, заключается в использовании хэш-карты или аналогичного, но мне было интересно узнать, есть ли метод, который я пропустил)

Ответы [ 5 ]

4 голосов
/ 29 марта 2012

Вы можете использовать extract и комбинировать его с array_map

extract(array_map('cleanInput', $_POST), EXTR_SKIP);

echo $name; // outputs name

Имейте в виду, что $ _POST could be что угодно, и пользователь может затем отправить что угодно на ваш сервер, и это станет переменной в вашемкод, таким образом, если у вас есть такие вещи, как

if(empty($varName)) { } // assumes $varName is empty initially

Может быть легко обойдено пользователем, отправив $_POST['varName'] = 1

Чтобы избежать подобных ошибок, вы можете иметь белый список массива и отфильтровать только тевам нужно:

$whitelist = array('name', 'phone', 'message');
$fields = array();

foreach($_POST as $k => $v) {
   if(in_array($k, $whitelist)) $fields[$k] = $v;
}

extract(array_map('cleanInput', $fields));
1 голос
/ 29 марта 2012

1) К первому вопросу, как объединить цикл if и for:

Зачем вам это нужно, это только затруднит чтение кода.Если ваш код требует if, а затем цикл for, то покажите этот факт, в этом нет ничего плохого.Если вы хотите сделать код более читабельным, вы можете написать функцию с подходящим именем, например, listAttachedFiles().

2). К вопросу об очистке пользовательского ввода:

Существует разница между входными данными проверки и экранированием .Это хорошая вещь для проверки ввода, например, если вы ожидаете число, то принимайте только цифры в качестве ввода.Но бежать не следует, пока вы не узнаете целевую систему.Поэтому оставьте ввод как есть, и перед записью в базу данных используйте функцию mysql_real_escape_string(), перед записью на HTML-страницу используйте функцию htmlspecialchars().

Объединение escape-функций до того, как это потребуется, может привести к получению неверных данных.,Это может стать невозможным для правильной выдачи в определенной целевой системе.

1 голос
/ 29 марта 2012

Лично я считаю, что затраты на производительность при использовании оператора «If» стоят того, чтобы иметь легко читаемый код.Кроме того, вы должны быть уверены, что на самом деле используете меньше циклов, комбинируя, если есть такой способ.

Я не уверен, что следую вашему второму вопросу, но вы смотрели на extract () и array_walk () еще?

0 голосов
/ 13 апреля 2012

Чтобы сделать цикл for более эффективным не используйте Count () в условии ваших циклов.

Это первое, чему они учат в школе.Поскольку циклы For переоценивают условия на каждой итерации.

$nbOfDocs = count($docNames); //will be much faster
for($i=0;$i<$nbOfDocs;$i++)
{
   $attachedFiles = $attachedFiles. " - " . $docNames[$i] . "\n";
}
0 голосов
/ 29 марта 2012

Точка 1 - преждевременная оптимизация. И вы хотите добиться лучшей производительности / читабельности при этом. (аналогично использованию массивов для всего).

Точка 2 - Ааааааааа! Вам следует только изменить представление данных в том месте, где они покидают PHP , используя метод подходящего к месту назначения, а не к месту его прибытия в PHP. 1009 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...