Аватар для 3kuta
5 / 5 / 0
Регистрация: 21.02.2020
Сообщений: 31

Подтверждение перезаписи при загрузке файла на сервер через форму

21.02.2020, 19:45. Показов 1824. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
У меня есть форма, которая загружает файл на сервер. Файл при загрузке меняет название на выбранную дату. Я хочу выдать подтверждение при загрузке файла, если такой файл уже существует и при нажатии на соответствующую кнопку заменить или не заменить файл. Для этого я создал папку tmp, в которую я помещаю временные файлы. И теоретически, когда вы нажимаете «да», файл из временной папки должен перезаписывать файл в основной.

HTML5
1
2
3
4
5
6
<form>
    <label for="date">Дата</label><input type="date" id="date" name="date">
    <label for="customFile">Выбрать отчет</label>
    <input type="file" id="customFile" name="report">
    <button type="submit">Load file to server</button>
</form>
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
if (isset($_POST['date'])){
$mysqli = new mysqli('localhost', 'root', '', 'report');
$date = $_POST['date'];
 
if ($_FILES['report']['name'] != ''){
 
    $dir = 'report/';
    $report = $dir . $date . '.xlsx';
    $tmp = $dir . 'tmp/' . $date . '.xlsx';
 
    if (file_exists($report)) {
        require('include/file_exists.php');
        copy($_FILES['report']['tmp_name'], $tmp);
    } else {
        copy($_FILES['report']['tmp_name'], $report);
        echo "File loaded<br>";
    }
}
?>
"file_exists.php":

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
 
if (isset($_POST['overwrite'])) {
    copy($tmp, $report);
    echo "File overwrite!<br>";
} else {
    echo "No button enter<br>";
}
?>
 
<form method="post">
    <div id="LoadReport">
        <p>Do you want to overwrite the file?</p>
        <button type="button">Нет</button>
        <button type="button" name="overwrite">Да</button>
    </div>
</form>
Понимаю, что переменные уже не передаются во вторую форму и обратно overwrite не возвращается, но что в таком случае можно сделать?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.02.2020, 19:45
Ответы с готовыми решениями:

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

Откуда взялся alert с текстом "Подтверждение действия на странице." при загрузке файла?
При загрузке файла (после выбора файла в проводнике) &lt;input type=&quot;file&quot; name=&quot;layout&quot; id=&quot;uploaded-file&quot;&gt; появляется alert,...

Переименование при загрузке через форму
Помогите пожалуйста, все перерыл уже! Как сделать переименование файла при загрузке через форму. Например, Пользователь загружает файл с...

19
 Аватар для sad67man
2484 / 1408 / 667
Регистрация: 23.08.2015
Сообщений: 3,550
21.02.2020, 20:30
3kuta, Кладите название временного файла в сессию под каким-нибудь ключом из рандомной строки. И через вторую форму передавайте этот ключ.
0
 Аватар для 3kuta
5 / 5 / 0
Регистрация: 21.02.2020
Сообщений: 31
21.02.2020, 20:38  [ТС]
Можно подробнее. Нуб в коде
0
 Аватар для sad67man
2484 / 1408 / 667
Регистрация: 23.08.2015
Сообщений: 3,550
21.02.2020, 21:13
Лучший ответ Сообщение было отмечено 3kuta как решение

Решение

3kuta, Я бы написал пару вспомогательных классов

PHP
1
2
3
4
5
6
7
8
9
10
11
12
class DtoFile
{
    public $id;
    public $report;
    public $tmp;
 
    public function __construct($report, $tmp)
    {
        $this->report = $report;
        $this->tmp = $tmp;
    }
}
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class TempFileStore
{
    public function save(DtoFile $dto): string
    {
        session_start();
        $dto->id = $this->generateKey();
        $_SESSION['tmpFile'][$dto->id] = [
            'report' => $dto->report,
            'tmp' => $dto->tmp
        ];
 
        return $dto;
    }
 
    public function get($id)
    {
        session_start();
        $data = $_SESSION['tmpFile'][$id] ?? null;
 
        if (empty($data)) {
            return null;
        }
 
        $dto = new DtoFile($data['report'], $data['tmp']);
        $dto->id = $id;
 
        return $dto;
    }
 
    public function clear()
    {
        session_start();
        unset($_SESSION['tmpFile']);
    }
 
    private function generateKey()
    {
        return md5(time());
    }
}
Теперь реализовать логику не составит труда.

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$store = new TempFileStore();
 
 
if (isset($_POST['date'])) {
    $mysqli = new mysqli('localhost', 'root', '', 'report');
    $date = $_POST['date'];
 
    if ($_FILES['report']['name'] != '') {
 
        $dir = 'report/';
        $dto = new DtoFile(
            $dir . $date . '.xlsx',
            $dir . 'tmp/' . $date . '.xlsx'
        );
 
        if (file_exists($dto->report)) {
            copy($_FILES['report']['tmp_name'], $dto->tmp);
            $store->save($dto);
            header('Location: file_exists.php?id=' . $dto->id);
            exit;
        } else {
            copy($_FILES['report']['tmp_name'], $dto->report);
            echo "File loaded<br>";
        }
    }
}
 
?>
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
 
$store = new TempFileStore();
 
if(!$dto = $store->get($_GET['id'] ?? '')) {
    header('Location: index.php');
    die();
}
 
 
if (isset($_POST['overwrite'])) {
 
    copy($dto->tmp, $dto->report);
    $store->clear();
 
    echo "File overwrite!<br>";
} else {
    echo "No button enter<br>";
}
?>
 
<form method="post">
    <div id="LoadReport">
        <p>Do you want to overwrite the file?</p>
        <button type="button">Нет</button>
        <button type="button" name="overwrite">Да</button>
    </div>
</form>
Добавлено через 1 минуту
Код не проверял. Надеюсь понятна идея.
1
 Аватар для 3kuta
5 / 5 / 0
Регистрация: 21.02.2020
Сообщений: 31
22.02.2020, 15:08  [ТС]
Как понимаю, что-то нужно с этим сделать:

PHP
1
2
3
4
$dto = new DtoFile(
    $dir . $date . '.xlsx',
    $dir . 'tmp/' . $date . '.xlsx'
);
Fatal error: Uncaught TypeError: Return value of TempFileStore::save() must be of the type string, object returned in C:\OSPanel\domains\ReportTest\class.php: 27 Stack trace: #0 C:\OSPanel\domains\ReportTest\index.php( 21): TempFileStore->save(Object(DtoFile)) #1 {main} thrown in C:\OSPanel\domains\ReportTest\class.php on line 27
0
 Аватар для sad67man
2484 / 1408 / 667
Регистрация: 23.08.2015
Сообщений: 3,550
22.02.2020, 15:19
3kuta,
PHP
1
2
3
4
5
6
7
8
9
10
11
public function save(DtoFile $dto): DtoFile
    {
        session_start();
        $dto->id = $this->generateKey();
        $_SESSION['tmpFile'][$dto->id] = [
            'report' => $dto->report,
            'tmp' => $dto->tmp
        ];
 
        return $dto;
    }
Добавлено через 1 минуту
3kuta, Я код просто не тестировал, по началу думал возвращать ключ. Т.е. строку, протом переделал на объект, а в методе
public function save(DtoFile $dto): string
Забыл поменять тип возвращаемого значения. Нужно
public function save(DtoFile $dto): DtoFile

Добавлено через 5 минут
Хотя в принципе нам то и не нужно ничего возвращать) Мы же это никак не используем.

PHP
1
2
3
4
5
6
7
8
9
public function save(DtoFile $dto)
    {
        session_start();
        $dto->id = $this->generateKey();
        $_SESSION['tmpFile'][$dto->id] = [
            'report' => $dto->report,
            'tmp' => $dto->tmp
        ];
    }
Добавлено через 1 минуту
Так как в php все объекты передаются по ссылке. Там мы кроме того, что сохраняем в сессию еще присваиваем id.
0
 Аватар для 3kuta
5 / 5 / 0
Регистрация: 21.02.2020
Сообщений: 31
22.02.2020, 15:39  [ТС]
В общем мне не разобраться)

Теперь похоже эта штука не получает ничего и редиректит, не показывая вторую форму, на главную.

PHP
1
2
3
4
if(!$dto = $store->get($_GET['key'] ?? '')) {
    header('Location: index.php');
    die();
}
Что на данный момент имею:

index.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
include 'class.php';
 
$store = new TempFileStore();
 
if (isset($_POST['date'])) {
//    $mysqli = new mysqli('localhost', 'root', '', 'report');
    $date = $_POST['date'];
 
    if ($_FILES['report']['name'] != '') {
 
        $dir = 'report/';
        $dto = new DtoFile(
            $dir . $date . '.xlsx',
            $dir . 'tmp/' . $date . '.xlsx'
        );
 
        if (file_exists($dto->report)) {
            copy($_FILES['report']['tmp_name'], $dto->tmp);
            $store->save($dto);
            header('Location: include.php?id=' . $dto->id);
            exit;
        } else {
            copy($_FILES['report']['tmp_name'], $dto->report);
            echo "File loaded<br>";
        }
    }
}
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <title>Форма ввода</title>
</head>
 
<body>
    <form method="post" enctype="multipart/form-data">
        <label for="date">Дата</label>
        <input type="date" id="date" name="date">
 
        <label for="customFile">Выбрать отчет</label>
        <input type="file" id="customFile" name="report">
 
        <button type="submit">Load file to server</button>
    </form>
</body>
 
</html>
include.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
include 'class.php';
 
$store = new TempFileStore();
 
if (isset($_POST['date'])) {
//    $mysqli = new mysqli('localhost', 'root', '', 'report');
    $date = $_POST['date'];
 
    if ($_FILES['report']['name'] != '') {
 
        $dir = 'report/';
        $dto = new DtoFile(
            $dir . $date . '.xlsx',
            $dir . 'tmp/' . $date . '.xlsx'
        );
 
        if (file_exists($dto->report)) {
            copy($_FILES['report']['tmp_name'], $dto->tmp);
            $store->save($dto);
            header('Location: include.php?id=' . $dto->id);
            exit;
        } else {
            copy($_FILES['report']['tmp_name'], $dto->report);
            echo "File loaded<br>";
        }
    }
}
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <title>Форма ввода</title>
</head>
 
<body>
    <form method="post" enctype="multipart/form-data">
        <label for="date">Дата</label>
        <input type="date" id="date" name="date">
 
        <label for="customFile">Выбрать отчет</label>
        <input type="file" id="customFile" name="report">
 
        <button type="submit">Load file to server</button>
    </form>
</body>
 
</html>

class.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class DtoFile
{
    public $id;
    public $report;
    public $tmp;
 
    public function __construct($report, $tmp)
    {
        $this->report = $report;
        $this->tmp = $tmp;
    }
}
 
class TempFileStore
{
    public function save(DtoFile $dto)
    {
        session_start();
        $dto->id = $this->generateKey();
        $_SESSION['tmpFile'][$dto->id] = [
            'report' => $dto->report,
            'tmp' => $dto->tmp
        ];
    }
 
    public function get($key)
    {
        session_start();
        $data = $_SESSION['tmpFile'][$key] ?? null;
 
        if (empty($data)) {
            return null;
        }
 
        $dto = new DtoFile($data['report'], $data['tmp']);
        $dto->id = $key;
 
        return $dto;
    }
 
    public function clear()
    {
        session_start();
        unset($_SESSION['tnpFile']);
    }
 
    private function generateKey()
    {
        return md5(time());
    }
}
В идеале конечно, все делать на одной странице, но как понимаю, одним php тут не обойтись.
0
 Аватар для sad67man
2484 / 1408 / 667
Регистрация: 23.08.2015
Сообщений: 3,550
22.02.2020, 15:59
3kuta, Я прошу прощения)) Это потому что мы редиректили с параметром id
header('Location: file_exists.php?id=' . $dto->id);
А пытаемся достать key
if(!$dto = $store->get($_GET['key'] ?? '')) {
Измените на id
if(!$dto = $store->get($_GET['id'] ?? '')) {

Добавлено через 16 минут
Цитата Сообщение от 3kuta Посмотреть сообщение
В идеале конечно, все делать на одной странице, но как понимаю, одним php тут не обойтись.
Смысла делать на одном php не вижу. Пользователь же по факту видит разные формы. + Это все-таки 2 разные операции.
Просто делать в одном php чисто из-за того, что это отностится к какой-то одной глобальной операции особого смысла нет. Так как потом будут возникать вопросы, типа "а почему у меня вместо одной стадии выводится другая и т.д. Я же тут кучу if/else понаписал, и не могу сам разобраться") Потом, если захотите можете перевести все это дело на ajax.
1
 Аватар для 3kuta
5 / 5 / 0
Регистрация: 21.02.2020
Сообщений: 31
22.02.2020, 16:13  [ТС]
Работает, УРА!

Похоже, что скоро пойду в ветку JS с таким вопросом)

Огромное спасибо за помощь.
0
 Аватар для 3kuta
5 / 5 / 0
Регистрация: 21.02.2020
Сообщений: 31
22.02.2020, 16:18  [ТС]
Собрал рабочую форму - мало ли кому понадобится...
Вложения
Тип файла: zip ReportTest.zip (1.9 Кб, 5 просмотров)
0
 Аватар для 3kuta
5 / 5 / 0
Регистрация: 21.02.2020
Сообщений: 31
22.02.2020, 16:28  [ТС]
sad67man, а возможно приостанавливать выполнения кода в index.php пока не получен ответ от второй формы?

У меня после

PHP
1
2
3
4
5
6
7
8
9
    if (file_exists($dto->report)) {
            copy($_FILES['report']['tmp_name'], $dto->tmp);
            $store->save($dto);
            header('Location: include.php?id=' . $dto->id);
            exit;
        } else {
            copy($_FILES['report']['tmp_name'], $dto->report);
            echo "File loaded<br>";
        }
выполняется INSERT в БД, и хотелось бы обратно передавать значение $_POST['overwrite'] и в зависимости от значения делать INSERT или нет.
0
 Аватар для sad67man
2484 / 1408 / 667
Регистрация: 23.08.2015
Сообщений: 3,550
22.02.2020, 16:43
3kuta, Лучше вынести ваш INSERT в отдельную функцию, либо метод класса для повторного использования. И вызвать в блоке $_POST['overwrite']

Добавлено через 3 минуты
3kuta, Если вам нужны будут дополнительные поля из формы. Вы можете их добавить в $dto, сохраняя их в сессии, соответственно нужно будет дополнить storage.

Добавлено через 2 минуты
И так-же в метод/функцию insert вы можете принимать ваш $dto
0
 Аватар для 3kuta
5 / 5 / 0
Регистрация: 21.02.2020
Сообщений: 31
22.02.2020, 17:29  [ТС]
sad67man, нужно время на изучение вопроса, так как понимания - 0 Спасибо за подсказку.
0
 Аватар для sad67man
2484 / 1408 / 667
Регистрация: 23.08.2015
Сообщений: 3,550
22.02.2020, 17:47
3kuta, Вы лучше код покажите)
0
 Аватар для 3kuta
5 / 5 / 0
Регистрация: 21.02.2020
Сообщений: 31
23.02.2020, 11:21  [ТС]
sad67man, сейчас это выглядит вот так:

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
include 'connect.php';
include 'func.php';
 
$store = new TempFileStore();
 
if (isset($_POST['date'])) {
//    $mysqli = new mysqli('localhost', 'root', '', 'report');
    $date = $_POST['date'];
    $name = $_POST['name'];
 
    if ($_FILES['report']['name'] != '') {
 
        $dir = 'report/';
        $dto = new DtoFile(
            $dir . $date . '.xlsx',
            $dir . 'tmp/' . $date . '.xlsx'
        );
 
        if (file_exists($dto->report)) {
            copy($_FILES['report']['tmp_name'], $dto->tmp);
            $store->save($dto);
            header('Location: include.php?id=' . $dto->id);
            exit;
        } else {
            copy($_FILES['report']['tmp_name'], $dto->report);
            echo "File loaded<br>";
            
        }
    }
    
    if (isset($_POST['name'])) {
        $result = $mysqli->query("INSERT INTO first (name) VALUES ('$name')"); 
    }
}
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <title>Форма ввода</title>
</head>
 
<body>
    <form method="post" enctype="multipart/form-data">
        <table>
            <tr>
                <td><label for="date">Дата</label></td>
                <td><input type="date" id="date" name="date"></td>
            </tr>
            <tr>
                <td><label for="name">Текст для БД</label></td>
                <td><input type="text" id="name" name="name"></td>
            </tr>
            <tr>
                <td><label for="customFile">Выбрать отчет</label></td>
                <td><input type="file" id="customFile" name="report"></td>
            </tr>
            <tr>
                <td colspan="2"><button type="submit">Load file to server</button></td>
            </tr>
        </table>
    </form>
    <hr>
    <h3>Таблица из БД</h3>
    <table border="1">
        <tr>
            <th>ID</th>
            <th>NAME</th>
        </tr>
        <?php
    
    $result = $mysqli->query('SELECT * FROM first');
    while ($row = mysqli_fetch_array($result)) {
    ?>
 
        <tr>
            <td><?= $row['ID']?></td>
            <td><?= $row['name']?></td>
        </tr>
 
        <?php
    }
    
    ?>
    </table>
</body>
 
</html>
0
 Аватар для 3kuta
5 / 5 / 0
Регистрация: 21.02.2020
Сообщений: 31
24.02.2020, 20:16  [ТС]
sad67man,

Как-то так:
index.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
include 'func.php';
 
$store = new TempFileStore();
 
if (isset($_POST['date']) && isset($_POST['name'])) {
    
    $con = new dbcon();
    
    $date = $_POST['date'];
    $name = $_POST['name'];
 
    if ($_FILES['report']['name'] != '') {
 
        $dir = 'report/';
        $dto = new DtoFile(
            $dir . $date . '.xlsx',
            $dir . 'tmp/' . $date . '.xlsx',
            $name
        );
 
        if (file_exists($dto->report)) {
            copy($_FILES['report']['tmp_name'], $dto->tmp);
            $store->save($dto);
            header('Location: include.php?id=' . $dto->id);
            exit;
        } else {
            copy($_FILES['report']['tmp_name'], $dto->report);
            echo "File loaded<br>";
            $con->insert_table($name);
        }
    }
}
func.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class dbcon
{
    public $mysqli;
    
    function __construct()
    {
        $this->mysqli = new mysqli('localhost', 'root', '', 'test');
        
        if (mysqli_connect_errno()) {
            printf("Невозможно подключиться к базе данных. Код ошибки: %s\n", mysqli_connect_error());
            exit;
        }
    }
    
    function insert_table($name)
    {
        $result = $this->mysqli->query("INSERT INTO first (name) VALUES ('$name')");
        return $result;
    }
}
include.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
include 'func.php';
 
$store = new TempFileStore();
 
if(!$dto = $store->get($_GET['id'] ?? '')) {
    header('Location: index.php');
    die();
}
 
if ($_POST['overwrite'] === '1') {
    copy($dto->tmp, $dto->report);
    $con = new dbcon();
    $con->insert_table($dto->name);
    $store->clear();
    
} elseif ($_POST['overwrite'] === '0') {
    header('Location: index.php');
}
Есть может замечания по коду?
0
 Аватар для sad67man
2484 / 1408 / 667
Регистрация: 23.08.2015
Сообщений: 3,550
25.02.2020, 01:49
3kuta, Не плохо), Вы уже начинаете осваивать ООП)

Замечания будут позже,
А пока ознакомьтесь с такой штукой. Есть список общепринятых стандартов
https://www.php-fig.org/psr/
Про каждый из них вы сможете найти объяснения на русском языке на просторах интернета.

Сейчас хочу обратить внимание на то, что каждый класс должен располагаться в отдельном файле.
Так же обратите внимание на psr-4 - автозагрузка классов.
Вот первая попавшееся статья https://klisl.com/composer_autoload.html

Сейчас ни один проект не обходится без composer-а
Если сможете с ним разобраться и перевести проект на автозагрузку классов через composer, то будет очень здорово)
0
 Аватар для 3kuta
5 / 5 / 0
Регистрация: 21.02.2020
Сообщений: 31
27.02.2020, 17:45  [ТС]
sad67man, а теперь?
Много кода, поэтому в архиве.

Появился еще вопрос: "Почему у меня на второй форме при нажатии только со второго раза срабатывает переход на главную?". Не могу разобраться

Расположение файлов во вложении скрином (1.PNG).

composer.json
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
    "name": "3kuta/report",
    "description": "html form onclick check if file exists [closed]",
    "type": "project",
    "license": "MIT",
    "authors": [
        {
            "name": "3kuta",
            "email": "pr.dorofeev@yandex.ru"
        }
    ],
    "minimum-stability": "stable",
    "require": {},
    "autoload": {
        "psr-4": {
            "Models\\": "src/Models/"
        }
    }
}
autoload_psr4.php
PHP
1
2
3
4
5
6
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
 
return array(
    'Models\\' => array($baseDir . '/src/Models'),
);
Пример класса:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
 
namespace Models\DbCon;
 
use Mysqli;
 
class DbCon
{
    public $mysqli;
    
    public function __construct()
    {
        $this->mysqli = new mysqli('localhost', 'root', '', 'test');
        
        if (mysqli_connect_errno()) {
            printf("Невозможно подключиться к базе данных. Код ошибки: %s\n", mysqli_connect_error());
            exit;
        }
    }
    
    public function insertTable($name)
    {
        $result = $this->mysqli->query("INSERT INTO first (name) VALUES ('$name')");
        return $result;
    }
    
    public function selectTable($tblrow, $tblname)
    {
        $result = $this->mysqli->query("SELECT ".$tblrow." FROM ".$tblname);
        
        return $result;
    }
}
index.php
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
require __DIR__ . '/vendor/autoload.php';
 
$store = new Models\TempFileStore\TempFileStore();
$con = new Models\DbCon\DbCon();
 
if (isset($_POST['date']) && isset($_POST['name'])) {
    
    
    $date = $_POST['date'];
    $name = $_POST['name'];
 
    if ($_FILES['report']['name'] != '') {
 
        $filename = $_FILES['report']['name'];
        $dir = 'load/';
        $tmp = $dir . 'tmp/';
        $ext = substr($filename, strpos($filename,'.'), strlen($filename)-1);
        $dto = new Models\DtoFile\DtoFile(
            $dir . $date . $ext,
            $tmp . $date . $ext,
            $name
        );
 
        if (file_exists($dto->report)) {
            copy($_FILES['report']['tmp_name'], $dto->tmp);
            $store->save($dto);
            header('Location: include.php?id=' . $dto->id);
            exit;
        } else {
            copy($_FILES['report']['tmp_name'], $dto->report);
            echo "File loaded<br>";
            $con->insertTable($name);
        }
    }
}
Миниатюры
Подтверждение перезаписи при загрузке файла на сервер через форму  
Вложения
Тип файла: zip ReportTest.zip (10.9 Кб, 2 просмотров)
0
 Аватар для sad67man
2484 / 1408 / 667
Регистрация: 23.08.2015
Сообщений: 3,550
27.02.2020, 18:27
Цитата Сообщение от 3kuta Посмотреть сообщение
Появился еще вопрос: "Почему у меня на второй форме при нажатии только со второго раза срабатывает переход на главную?". Не могу разобраться
PHP
1
2
3
4
5
6
7
8
9
10
11
if ($_POST['overwrite'] === '1') {
    copy($dto->tmp, $dto->report);
    $con = new DbCone();
    $con->insertTable($dto->name);
    $store->clear();
 
    header('Location: index.php');
 
} elseif ($_POST['overwrite'] === '0') {
    header('Location: index.php');
}
После выполнения операции нужно редирект поставить)

Цитата Сообщение от 3kuta Посмотреть сообщение
а теперь?
Чуть позже посмотрю) сейчас времени нет, ближе к выходным.
0
 Аватар для sad67man
2484 / 1408 / 667
Регистрация: 23.08.2015
Сообщений: 3,550
06.03.2020, 23:38
3kuta, Ну чтож, пойдем дальше. Я не знаю на сколько вы продвинулись. Пройдемся для начала по критическим моментам.
1) это безопасность.
Первое, это вывод значений, если я при заполнении формы напишу какие-нибудь теги. То в лучшем случае у вас полетит верстка, а могут и внедрить скрипты, типа <script>alert(123)</script>

Есть такая функция htmlspecialchars. Которая преобразует специальные символы в HTML-сущности. Тогда вывод должен быть таким.

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<h3>Таблица из БД</h3>
<table border="1">
    <tr>
        <th>ID</th>
        <th>NAME</th>
    </tr>
    <?php$result = $con->selectTable('*', 'reports');
    while ($row = mysqli_fetch_array($result)): ?>
 
        <tr>
            <td><?= htmlspecialchars($row['id']) ?></td>
            <td><?= htmlspecialchars($row['name']) ?></td>
        </tr>
 
    <?php endwhile; ?>
</table>
Обратите внимание, что когда мы находимся в контексте html кода, то мы для конструкций не используем фигурные скобки, а : end. Т.е.
PHP/HTML
1
2
3
4
5
6
7
<div>
    <?php if (true): ?>
        <p>Да</p>
    <?php else: ?>
        <p>Нет</p>
    <?php endif ?>
</div>
А когда мы находимся в контексте php то используем фигурные скобки.

Ну чтоб каждый раз не писать htmlspecialchars можно написать некий хэлпер

PHP
1
2
3
4
5
6
7
class Html
{
    public static function encode($str)
    {
        return htmlspecialchars($str, ENT_QUOTES | ENT_SUBSTITUTE);
    }
}
Здесь мы добавили еще некоторые настройки.

Теперь можем выводить так

PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<h3>Таблица из БД</h3>
<table border="1">
    <tr>
        <th>ID</th>
        <th>NAME</th>
    </tr>
    <?php$result = $con->selectTable('*', 'reports');
    while ($row = mysqli_fetch_array($result)): ?>
 
        <tr>
            <td><?= Html::encode($row['id']) ?></td>
            <td><?= Html::encode($row['name']) ?></td>
        </tr>
 
    <?php endwhile; ?>
</table>
Добавлено через 11 минут
Далее, мы в шаблоне html обращаемся к базе данных
PHP
1
$con->selectTable('*', 'reports')
Это не красиво и не правильно. В идеале в шаблон должны поступать уже готовые данные. Причем в контексте шаблона нам абсолютно не важно откуда эти данные были взяты.
Представьте, что у нас есть 2 контекста. Первый - это блок php. А второй это шаблон. И php в зависимости от контекста выполняет 2 различные функции. В первом случае это серверный язык, а в другом обычный шаблонизатор.

Вынесем эту логику в блок php.

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
 
use src\DbCon;
use src\DtoFile;
use src\helpers\Html;
use src\TempFileStore;
 
require __DIR__ . '/vendor/autoload.php';
 
$store = new TempFileStore();
$con = new DbCon();
 
if (isset($_POST['date']) && isset($_POST['name'])) {
    ...
}
 
$reports = [];
$result = $con->selectTable('*', 'reports');
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
    $reports[] = $row;
}
 
 
?>
А в шаблоне тогда используем простой foreach

PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
<h3>Таблица из БД</h3>
<table border="1">
    <tr>
        <th>ID</th>
        <th>NAME</th>
    </tr>
    <?php foreach ($reports as $report): ?>
        <tr>
            <td><?= Html::encode($row['id']) ?></td>
            <td><?= Html::encode($row['name']) ?></td>
        </tr>
    <?php endforeach ?>
</table>
А еще лучше это инкапсулировать в метод класса.
PHP
1
$reports = $con->getReportsList();
До класса Dbcon мы еще доберемся.

Добавлено через 21 минуту
И второй момент. Более критический. Это SQL инъекции. В форме я могу ввести такую строку, которая поломает сам sql запрос. Более того, могу внедрить свой запрос, ну к примеру.

PHP
1
2
$name = "5'); DROP TABLE reports; INSERT INTO users (name) VALUES ('Вася";
$result = $this->mysqli->query("INSERT INTO reports (name) VALUES ('$name')");
Если мы напрямую подставим значение в sql запрос. то получим
PHP
1
$this->mysqli->query("INSERT INTO reports (name) VALUES ('5'); DROP TABLE reports; INSERT INTO users (name) VALUES ('Вася')");
Для этого лучше использовать подготовленные запросы.
PDO:: prepare

Я вам рекомендую вместо misqli использовать PDO. Так как он более универсален, и может работать не только с mysql. Это будет ваше "домашнее задание"). Если будете справляться. То тогда расскажу еще кучу полезных вещей)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
06.03.2020, 23:38
Помогаю со студенческими работами здесь

Название файла при загрузке на сервер
&lt;? $filew = $_FILES; $filename = $_FILES; if(!empty($filew)) { ini_set('memory_limit', '32M'); $maxsize = &quot;100000000&quot;; ...

Переименовать изображение при загрузке на сервер через uniqid
Загружаю изображение через форму таким образом $file=$_FILES; $image= addslashes(file_get_contents($_FILES)); $image_name=...

При загрузке файла на сервер меняется кодировка
Здравствуйте, возник такой вопрос: Написал код для загрузки на сервер, файлы загружаются все хорошо, только когда загружаю файлы с русским...

Кодировка при загрузке файла на FTP сервер
Здравствуйте, у меня возникла проблема с правильной загрузкой файла на FTP сервер. Файл загружается, но русские символы показываются в виде...

Не сохраняется имя файла при загрузке на сервер
Привет друзья. Такая ситуация. Есть страничка добавления своего баннера в ротацию. Указываю ссылку на сайт, выбираю баннер на ПК, нажимаю...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

Новые блоги и статьи
Система статов в Unity
GameUnited 20.04.2025
Статы — фундаментальный элемент игрового дизайна, который определяет характеристики персонажей, предметов и других объектов в игровом мире. Будь то показатель силы в RPG, скорость передвижения в. . .
Статические свойства и методы в TypeScript
run.dev 20.04.2025
TypeScript прочно занял своё место в системе современной веб-разработки. Этот строго типизированный язык программирования не просто расширяет возможности JavaScript — он делает разработку более. . .
Batch Transform и Batch Gizmo Drawing API в Unity
GameUnited 20.04.2025
В мире разработки игр и приложений на Unity производительность всегда была критическим фактором успеха. Создатели игр постоянно балансируют между визуальной привлекательностью и плавностью работы. . .
Звук в Unity: Рандомизация с Audio Random Container
GameUnited 20.04.2025
В современных играх звуковое оформление часто становится элементом, который либо полностью погружает игрока в виртуальный мир, либо разрушает атмосферу за считанные минуты. Представьте: вы исследуете. . .
Максимальная производительность C#: Советы, тестирование и заключение
stackOverflow 20.04.2025
Погружение в мир микрооптимизаций C# открывает перед разработчиком целый арсенал мощных техник. Но как определить, где и когда их применять? Ответ начинается с точных измерений и профилирования. . . .
Максимальная производительность C#: Предсказание ветвлений
stackOverflow 20.04.2025
Третий ключевой аспект низкоуровневой оптимизации — предсказание ветвлений. Эта тема менее известна среди разработчиков, но её влияние на производительность может быть колоссальным. Чтобы понять. . .
Максимальная производительность C#: Векторизация (SIMD)
stackOverflow 20.04.2025
Помимо работы с кэшем, другим ключевым аспектом низкоуровневой оптимизации является векторизация вычислений. SIMD (Single Instruction, Multiple Data) позволяет обрабатывать несколько элементов данных. . .
Максимальная производительность C#: Процессорный кэш
stackOverflow 20.04.2025
Знакомство с внутренним устройством процессорного кэша — ключевой шаг в написании по-настоящему быстрого кода на C#. Этот слой архитектуры компьютера часто ускользает от внимания разработчиков, но. . .
Максимальная производительность C#: Введение в микрооптимизации
stackOverflow 20.04.2025
В мире разработки на C# многие привыкли полагаться на . NET Runtime, который "магическим образом" сам оптимизирует код. И часто это работает - современные JIT-компиляторы творят чудеса. Но когда речь. . .
MVC фреймворк в PHP
Jason-Webb 19.04.2025
Архитектурный паттерн Model-View-Controller (MVC) – это не просто модный термин из мира веб-разработки. Для PHP-программистов это фундаментальный подход к организации кода, который радикально меняет. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru