2014-01-02 3 views
0

У меня есть сайт PHP, на котором зарегистрированные пользователи могут загружать аватар. Одним из ограничений является то, что люди могут загружать только файл .jpg или .jpeg только с буквенно-цифровыми символами, все остальное отклоняется. Это делается для того, чтобы я получал только загрузки, такие как «avatar.jpg», а не «evilcode.php» или «secretcode.php.jpg». Я также планирую другие проверки, но сейчас я не могу сделать этот первый шаг для работы.Использование regex в PHP для фильтрации допустимых имен файлов

Я использую это регулярное выражение:

[a-zA-Z0-9]{1,150}+\.+(jpe?g) 

Это код, который я сейчас использую. Функция вызывается из другого php-файла с параметром $ _FILES ['avatar'].

public function updateAvatar($avatar) 
{ 
    $regex = '^[a-zA-Z0-9]{1,100}+\.+(jpe?g)$'; 
    $name = $avatar['name'];  
    $result = preg_match_all($regex, $name); 
    if($result === 1) 
    { 
     return true; 
    } else 
    { 
     return false; 
    } 
} 

Это всегда возвращает ложь, при загрузке либо "avatar.jpg", "code.php", или "duck.gif". Согласно руководству PHP, этот код должен быть правильным. Метод возвращает либо целое число, либо логическое значение, и предупреждает, что вы должны использовать ===, not == для сравнения результата. Кто-нибудь знает, что я сделал неправильно?

+3

Следует проверить тип MIME загруженного файла. – Marty

+0

Без фактической проверки этой идеи .. Я думаю, что результат будет равен 2, а не 1, весь шаблон = 1 + группа = 2 – Dale

ответ

2

Когда вы Проверьте ваш входящий файл через регулярное выражение, можно загрузить exploit file с исполняемым мимики, так что вы должны проверить мим файла для безопасной загрузки:

public function updateAvatar($avatar) 
{ 
    $available_mimes = array(
     'jpeg' => 'image/jpeg', 
     'jpg' => 'image/jpg', 
     'iejpg' => 'image/pjpeg' // this mime sent Internet Explorer for jpg files 
    ); 

    if(in_array($avatar['type'], $available_mimes) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

Что касается вашей функции регулярных выражений:

public function updateAvatar($avatar) 
{ 
    // Use regex with ignore case flag (for validating jpg and JPG) 

    // Uncomment next line, if you want to check files with "_" symbols at name 
    // if(preg_match('/^(\w+)\.(jpe?g)$/i', $avatar['name'])) 

    if(preg_match('/^([a-z0-9]+)\.(jpe?g)$/i', $avatar['name'])) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

И пытаются использовать preg_match()

+0

'\ w' будет соответствовать' _' слишком – revo

+0

, если это проблема, используйте '/^([a-z0-9]+)\.(jpe?g)$/i'. Но «_» является правильным символом для имен файлов –

+0

Я знаю, но OP говорит «только буквенно-цифровые символы» – revo

-1

Добавить разделители для вашего выражения регулярных выражений, попробуйте следующее:

$regex = '/^[a-zA-Z0-9]{1,100}+\.+(jpe?g)$/'; 
//  ^       ^
+0

_I просто интересно, почему этот ответ получил 3 пропущенных вниз! _ – revo

+0

Я думал то же самое. .. Я пошел прямо к делу, и это решает проблему! –

+0

+1, Nevermind;) – revo

0

Я вижу две проблемы. Во-первых, функции RegEx PHP ожидают, что шаблоны будут окружены символами-разделителями по вашему выбору (параметры регулярного выражения идут после конечного разделителя).

Например: $regex = '/^[a-zA-Z0-9]{1,100}+\.+(jpe?g)$/'; или $regex = '|^[a-zA-Z0-9]{1,100}+\.+(jpe?g)$|';

Во-вторых, можно использовать как {1,100} («Есть один к 100 characers из указанного класса»), а также + ("есть один или несколько charecter из указанного класса «). Используйте только один из них.

0

попытаться использовать это,

/\.(jpg|jpeg|png|gif)(?:[\?\#].*)?$/i 
1

Ваше регулярное выражение не имеет ограничителей:

/^[a-zA-Z0-9]{1,100}+\.+(jpe?g)$/ 

и вам не нужно preg_match_all(), как вы проверяете одно имя аватара файла:

public function updateAvatar($avatar) 
{ 
    $regex = '/^[a-zA-Z0-9]{1,100}+\.+(jpe?g)$/'; 
    $name = $avatar['name'];  
    if(preg_match($regex, $name)) 
     return true; 
    return false; 
} 

Однако вы бы лучше изменить ваш регулярное выражение для этого:

/^[a-zA-Z0-9]{1,100}\.(jpe?g)$/ 

в + знак после quantifie rs не требуется, также вы не должны проверять несколько dot s в конце имени в качестве ваших требований.

Live demo

+0

Зачем голосовать? – revo

Смежные вопросы