#php #mysql
#php #mysql
Вопрос:
Я написал код для загрузки файла Excel из базы данных mysql на PHP. Но где, как я хочу загрузить настроенный файл Excel из базы данных. Например, в моей базе данных есть name, inst1date, inst2date, inst3date…. Я хочу, чтобы в моем excel было поле name и date, где дата будет между двумя датами, которые я буду вводить. Он выбирает имена и соответствующие inst1date или inst2date или inst3date…. где это соответствует.
<?php
// include "config_1.php";
// ini_set('display_errors', 1); ini_set('log_errors',1); error_reporting(E_ALL); mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
include('db_con.php');
$todo=$_POST['todo'];
$search_text=$_POST['search_text'];
$todo2=$_POST['todo2'];
$search_text2=$_POST['search_text2'];
$query="select * from installment where inst1date between '$search_text' and '$search_text2' or inst2date between '$search_text' and '$search_text2' or inst3date between '$search_text' and '$search_text2'";
$stmt=$db_con->prepare($query);
$stmt->execute();
$columnHeader ='';
$columnHeader = "Sr NO"."t"."Roll"."t"."Name"."t"."Parent Name"."t"."Course Name"."t"."Course Fees"."t"."Batch"."t"."Due Amount"."t"."Admission Date"."t"."Admission Amount"."t"."Admission Status"."t"."Installment 1 Date"."t"."Installment 1 Amount"."t"."Installment 1 Status"."t"."Installment 2 Date"."t"."Installment 2 Amount"."t"."Installment 2 Status"."t"."Installment 3 Date"."t"."Installment 3 Amount"."t"."Installment 3 Status"."t"."Installment 4 Date"."t"."Installment 4 Amount"."t"."Installment 4 Status"."t"."Installment 5 Date"."t"."Installment 5 Amount"."t"."Installment 5 Status"."t"."Installment 6 Date"."t"."Installment 6 Amount"."t"."Installment 6 Status"."t"."Installment 7 Date"."t"."Installment 7 Amount"."t"."Installment 7 Status"."t"."Installment 8 Date"."t"."Installment 8 Amount"."t"."Installment 8 Status";
$setData='';
while($rec =$stmt->FETCH(PDO::FETCH_ASSOC))
{
$rowData = '';
foreach($rec as $value)
{
$value = '"' . $value . '"' . "t";
$rowData .= $value;
}
$setData .= trim($rowData)."n";
}
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=duelist.xls");
header("Pragma: no-cache");
header("Expires: 0");
echo ucwords($columnHeader)."n".$setData."n";
?>
Database table :
----------------
______________________________________________________________
Name | inst1date | inst2date | inst3date
_____________|_______________|______________|_________________
Arjun | 2019-03-02 | 2019-04-03 | 2019-05-04
_____________|_______________|______________|_________________
Sachin | 2019-04-05 | 2019-05-06 | 2019-06-07
Input Date 2019-04-02 To 2019-04-09
-----------------------------------
Expected Output Excel Structure
-------------------------------
Name | Date
____________|_______________
Arjun | 2019-04-03
____________|________________
Sachin | 2019-04-05
Комментарии:
1. Предупреждение: вы широко открыты для SQL-инъекций и должны действительно использовать параметризованные подготовленные операторы вместо того, чтобы вручную создавать свои запросы. Они предоставляются PDO или MySQLi . Никогда не доверяйте никаким входным данным, особенно тем, которые поступают со стороны клиента. Даже если ваши запросы выполняются только доверенными пользователями, вы все равно рискуете повредить свои данные .
Ответ №1:
Настройте свой SQL
$query= '
SELECT
name, DATE_FORMAT(inst1date, "%M %d %Y") AS inst1date ...
FROM installment
WHERE inst1date BETWEEN `'.$search_text.'` and `'.$search_text2.'`
LIMIT 100
';
- Вы ДОЛЖНЫ экранировать свои переменные или подвергаться риску SQL-инъекции. я предлагаю использовать php PDO или mysqli.
- избегайте использования
*
, поскольку он получит все из таблицы, что может быть не всем необходимым. Вместо этого используйте field1, field2- DATE_FORMAT может форматировать SQL во множестве различных форматов
- Вместо того, чтобы использовать mysql для форматирования даты, вы можете использовать php
$d = date("format", time);
—Обновить
ВЫБЕРИТЕ * ИЗ установки, ГДЕ ( inst1date МЕЖДУ '.$search_text.'
и '.$search_text2.'
) ИЛИ ( inst2date МЕЖДУ '.$search_text.'
и '.$search_text2.'
) ИЛИ ( inst3date МЕЖДУ '.$search_text.'
и '.$search_text2.'
) ОГРАНИЧЕНИЕ 100
Вернет строки, в которых любой из inst1date, inst2date или inst3date находится между поисковыми терминами. Вам необходимо обработать результаты на PHP, поскольку ваша таблица плохо разработана для запросов такого типа.
while($rec =$stmt->FETCH(PDO::FETCH_ASSOC)){
$rowData = '';
foreach($rec as $key => $value)
{
if(
( $key == 0 ) || // Will pass for the name param as it is the first in your row
(
$rec["inst1date"]) >= strtotime($search_text) amp;amp; strtotime($rec["inst1date"]) <= strtotime($search_text)
)||
// Repeat for inst2date and inst3date
){
$value = '"' . $value . '"' . "t";
$rowData .= $value;
}
}
$setData .= trim($rowData)."n";
}
// Это решение на php. Это грязно, потому что таблица SQL довольно грязная
Изменение sql-запроса даст гораздо лучшие результаты
SELECT
name,
#You could also add a format function too
CASE
WHEN inst1date BETWEEN `'.$search_text.'` and `'.$search_text2.'` THEN inst1date
WHEN inst2date BETWEEN `'.$search_text.'` and `'.$search_text2.'` THEN inst2date
ELSE inst3date
END AS date
FROM installment
WHERE
(
inst1date BETWEEN `'.$search_text.'` and `'.$search_text2.'`
) OR
(
inst2date BETWEEN `'.$search_text.'` and `'.$search_text2.'`
) OR
(
inst3date BETWEEN `'.$search_text.'` and `'.$search_text2.'`
)
LIMIT 100
Приведенный выше запрос вернет только два поля (поле имени и поле даты)
— Второе обновление
Я думаю, что если вы реорганизуете свою таблицу таким образом, было бы на 100% проще запрашивать. Пример:
id | name | date
________|____________|_______________
1 | Arjun | 2019-04-03 23:00:01
________|____________|________________
2 | Sachin | 2019-04-05 22:00:01
________|____________|________________
3 | Sachin | 2019-06-05 21:00:01
Просто продолжайте вставлять в таблицу для каждой instdate, которую вы хотите отслеживать. Использование идентификатора пользователя и объединений было бы еще лучше (замените имя на user_id из таблицы users)
$query= '
SELECT
CONCAT(u.first_name, " ", u.last_name) AS name,
DATE_FORMAT(date, "%Y-%m-%d") AS date
FROM installment AS i
JOIN users AS u ON u.id = i.user_id
WHERE date BETWEEN `'.$search_text.'` and `'.$search_text2.'`
#OPTIONALLY ADD GROUP BY TO LIMIT RESULTS
LIMIT 100
';
Использование вышеизложенного будет использовать реляционный характер БД. Рефакторинг строки по вертикали вместо по горизонтали позволит вам выполнять inst1date, inst2date, inst3date, inst4date и так далее. С каждой записью вы фактически добавляете еще одно поле даты. Как ни странно, вы можете видеть, что это лучший метод организации. Кроме того, вы можете создавать более подробные запросы, поскольку вы можете содержать больше данных без необходимости постоянно добавлять поля.
Комментарии:
1. Извините. Я отредактировал свой код. Теперь вы можете понять, что я хочу получить в качестве вывода
2. Посмотрите на мои предложения: либо используйте php для форматирования даты
date("Y-m-d", field)
, либо используйте mysql для форматирования вашего поля датыDATE_FORMAT(inst1date, %Y-%m-%d")
. также, что находится в таблице? * собирается получить все, похоже, вам нужны только два поля (имя, дата) -> настройте свой SQL3. Я хочу подобрать имена и даты, где они совпадают. После получения дат я хочу поместить их в файл Excel. Я не могу настроить свой файл Excel,
4. какие поля находятся в вашей таблице? с помощью * будут выбраны все поля. Будьте конкретны
5. Пожалуйста, посмотрите на мой код, тогда вы поймете, что я пытаюсь.