@m1rvi

Почему не работает код?

Я достаю массив с данными из sql запроса, то есть хочу получить по нему данные определенных юзеров, foreachем создаю файлы excel с юзерами, помещаю их в архив, затем скачиваю его(архив c excel юезров). ..так вот.. Как я говорил ^ ранее, я достаю только некоторые учетные записи по WHERE, но почему-то вместо к примеру 6 таких найденых записей, он скачивает все 10.000 учеток

код php

if(isset($_POST['EXCEL_DOWNLOAD'])) {
    //кнопка создания excel документа и его скачивание

//подключение
                require_once 'PHPExcel/Classes/PHPExcel.php';
//это библиотека phpexcel
                
function getUserses() {
//функция чтобы достать юзеров, которые ищем
    global $link;
    
$data = array();
 
if(!empty($_POST['phone'])) {
$data[] = "`phone`='".$_POST['phone']."'";
//если инпат с телефоном не пустой..
}
 
if(!empty($_POST['name'])) {
$data[] = "`name`='".$_POST['name']."'";
//если инпат с именем не пустой..
}
 
if(!empty($_POST['surname'])) {
$data[] = "`surname`='".$_POST['surname']."'";
//если инпат с фамилией не пустой..

}
 
if(!empty($_POST['region'])) {
$data[] = "`filial_id`='".$_POST['region']."'";
//если инпат с регионом не пустой..

}

if(!empty($_POST['parent'])) {
$data[] = "`parent_id`='".$_POST['parent']."'";
//если инпат с id реферала не пустой..

}
 
if(count($data) > 0)
{
  $sql= "SELECT * FROM `users` WHERE ".implode(' AND ', $data);
//если хоть один инпат не пустой, то implode

}
 else {
 $sql= "SELECT * FROM `users`";
//если все пустое 
 }
 
    $res=mysqli_query($link, $sql);
//сам запрос

$users=mysqli_fetch_all($res, MYSQLI_ASSOC);
//здесь ассоц. массив 

return $users;
}
$users = getUserses();
//думаю не надо объеснять 

$zip = new ZipArchive(); 
//создание новой zip папки
//нужно, чтобы помещать все excel сюда


$zip->open("archive_excel/archive.zip", ZIPARCHIVE::CREATE); 
//начинаем с ней работать

foreach($users as $user) {
//здесь обхожу каждого юзера из МАССИВА, чтобы из них сделать EXCEL файл, сохранить их и тд.

$objExcel = new PHPExcel();
$objExcel
->setActiveSheetIndex(0)
->setCellValue('A1', 'ID')
->setCellValue('B1', $user['id'])
->setCellValue('A2', 'ФИО')
->setCellValue('B2', $user['surname'] . " " . $user['name'] . " " . $user['thirdname'])
->setCellValue('A3', 'ID-Пригласителя')
->setCellValue('B3', $user['parent_id'])
->setCellValue('A4', 'Номер')
->setCellValue('B4', $user['phone'])
->setCellValue('A5', 'Регион')
->setCellValue('B5', $user['name'])
->setCellValue('A6', 'Баланс')
->setCellValue('B6', $user['bonus_1'])
->getColumnDimension('B')->setWidth(50);
//это все настройки для excel, не на это внимание

$objWriter = PHPExcel_IOFactory::createWriter($objExcel, 'Excel5');
$objWriter->save('archive_excel/'.$user['id'].'.xls');
//сохранение excel 

$retFile = $zip->addFile("archive_excel/".$user['id'].'.xls'); 
//копирование этого файла в ту самую zip папку

}
$zip->close(); 
//закончили работать с zip

foreach($users as $user) {
unlink('archive_excel/'.$profile['id'].'.xls');
}
//нужно удалить все ранее скопированные файлы 

$file_name= "archive_excel/archive.zip";
header("Content-Length: ".filesize($file_name));
header("Content-Disposition: attachment; filename=".$file_name);
header("Content-Type: application/x-force-download; name=\"".$file_name."\"");
readfile($file_name);
//скачивание файла
}




форма php

<form action="<?php echo $url ?>" method="POST" id="search_stat">
    <div class="search_flex">  <h1 style="margin-bottom: 0px;">+7</h1> <input type="number" name="phone" maxlength="10" value="<?php echo $_POST['phone']?>" class="btn_search"> <input type="submit" value="" id="search_click" name="goSearch">       <br> 
    <input type="submit" value="EXCEL" name="EXCEL_DOWNLOAD">
    </div>
      <br> 
        <input type="text" name="name" placeholder="Имя">
                <input type="text" name="surname" placeholder="Фамилия">
    <input type="text" name="region" placeholder="Регион">
    <input type="number" name="parent" placeholder="ID Пригласителя">

    <br> 
    </form>



Мысль кода такая.. На сайте есть расширенный поиск по юзерам, и при надобности можно скачать excel файлы c найдеными юезерами..

Проблема в том, что код скачивает все 10.000 учеток, вместо например найденых 6
  • Вопрос задан
  • 137 просмотров
Решения вопроса 2
index0h
@index0h
PHP, Golang. https://github.com/index0h
1. НИКОГДА не публикуйте креды к базе!
2. Не используйте подстановку данных в запрос через конкатенацию. Вместо этого используйте плейсхолдеры.
Пример 1 (SQL инъекция):
# Тут заэнкожено: '; DROP TABLE `users`; --
curl -XPOST -H 'Content-type: application/x-www-form-urlencoded' -d'phone=%27%3B%20DROP%20TABLE%20%60users%60%3B%20--'

Пример 2 (phone может содержать массив):
curl -XPOST -H 'Content-type: application/x-www-form-urlencoded' -d'phone[]=+123'

3. Не используйте глобальные переменные. Про это есть множество статтей.
4. Если есть возможность - используйте \PDO, вместо mysqli.
5. Не стоит объявлять функции/классы/трейты/интерфейсы по условию. Вместо этого используйте их по условию, но объявляйте без него.
6. При работе с путями рекомендую пользоваться глобальными, вместо относительных, иначе этот самый путь будет зависеть от скрипта, с которого запустили ваш код, а не от того, где происходит работа с файлами.
7. У вас конкурентно не безопасный код за счет того, что работа с файлами происходит в одном и том же каталоге, с одними и теми же именами файлов. Что будет если запустить два запроса одновременно на вытяжку всех пользователей? В лучшем случае один из запросов просто упадет с ошибкой что не может добавить в архив файл (это второй поток его уже удалил). Если будет запущено 2 запроса например на 1го пользователя и на всех - есть вероятность, что один из них вернет далеко не запрашиваемые данные)).
8. Очень рекомендую разделить вашу обработку на 2 части:
- Первая пусть записывает в файлики данные по пользователям при обновлении данных этих пользователей.
- Вторая - вытягивает вытягивает только id требуемых для архивирования и уже добавляет их в архив. Имя архива стоит делать рэндомным, что бы избежать конкурентного доступа к одному и тому же файлу на запись.
9. getUserses -> getUsers

Конкретно по вашей проблеме: если я праивльно понимаю, вы в один и тот же архив запихиваете файлы на каждый запрос, грубо говоря один раз вытянув всех пользователей - дальше вы только обновляете их в архиве на 10к файлов, а не создаете новый архив.
Ответ написан
@Alex_At_Net
Обращайтесь, помогу - https://t.me/codecraft_phd
Ваш код выглядит правильно. Я думаю, что лучше всего будет пропробовать распечатать запрос. Например, сохраните его в файл или в лог. Проверьте, что запрос с WHERE корректно собрался.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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