Повторяющаяся вставка MySQL, похоже, не работает

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

function insertToTable($dire){
    include "./modular/filesLogic.php";
    $scanf = scandir($dire);
    unset($scanf[array_search('.', $scanf, true)]);
    unset($scanf[array_search('..', $scanf, true)]);
        
    for($s = 2; $s<count($scanf); $s++){
        $iextension = pathinfo($scanf[$s], PATHINFO_EXTENSION);
        $inamewoext = pathinfo($scanf[$s], PATHINFO_FILENAME);
        $datec = date("Y-m-d");
        $sze = filesize($dire."/".$scanf[$s]);

        $seql = "SELECT * FROM files WHERE name='$inamewoext'";
        $resi = mysqli_query($conn, $seql);
            
        if (is_dir($scanf[$s])){
            $iextension = "dir";
            insertToTable($scanf[$s]);
        }

        if (mysqli_num_rows($resi) <= 0){
            $seeql = "INSERT INTO files (name, ftype, dateup, size, downloads, dirGroup) VALUES ('$inamewoext', '$iextension', '$datec', $sze, 0, '$dire')";
            $ress = mysqli_query($conn, $seeql);
        }
    }
}
insertToTable("uploads");

Добро пожаловать в СО. Что в filesLogic.php? Какой смысл в $iextension = "dir";, когда вы встречаете каталог? Кроме того, будьте осторожны с терминологией, «Инъекция MySQL» означает нечто совершенно отличное от того, о чем вы спрашиваете.

Don't Panic 16.04.2024 07:51

filesLogic.php содержит код для подключения ($conn) к моей базе данных. Он включает в себя код для загрузки и скачивания файлов в базу данных и из нее. Я хотел посмотреть, запишет ли он $ieextension как «dir» в моей базе данных, когда встретит каталог. Понятно, извините, я перефразирую название, спасибо @Don'tPanic

KleiaTMT 16.04.2024 08:11

Возможно, вам придется использовать что-то вроде $dire . '/' . $scanf[$s] для is_dir() и insertToTable(). Проблема в том, что вам необходимо указать правильный путь к каталогу для проверки и сканирования.

KIKO Software 16.04.2024 08:16

Включение соединения с БД в рекурсивную функцию без логики проверки того, было ли оно уже включено, кажется расточительным. Зачем использовать $s = 2 в цикле for — это для того, чтобы свести на нет записи . и ..?

Professor Abronsius 16.04.2024 08:20

Мой index.php включает соединение с БД, но по какой-то причине, когда я создаю функцию php, соединения, похоже, не работают, поэтому я включил соединение с БД во все мои функции. Да, $s = 2 предназначен для отрицания записей . и ... Я подумал, что так будет лучше, поскольку, хотя они и отключены, они все равно включаются, когда я вставляю файлы в базу данных. @ПрофессорАбронсиус

KleiaTMT 16.04.2024 08:27

Это потому, что вы используете $conn внутри функции в локальной области, тогда как $conn определяется в глобальной области filesLogic.php. Когда вы включаете filesLogic.php вне функции, вы можете добавить $conn в качестве аргумента функции (предпочтительно) или добавить global $conn; внутри функции. См.: Область действия переменной.

KIKO Software 16.04.2024 08:29

Спасибо @KIKOSoftware, я отредактирую эти части своего кода в будущем. Что касается $dire . '/' . $scanf[$s], похоже, он все еще не работает. Я продолжаю добавлять файлы в папку «загрузки», и они вставляют их в базу данных, поэтому я действительно думаю, что это связано либо с размещением моего вызова функции, либо с переменной, которую я вставил в нее.

KleiaTMT 16.04.2024 08:43

Ваш подход $s = 2 означает, что последние два элемента вашего массива $scanf не будут обработаны, поскольку массив теперь на два элемента короче, но первый индекс равен 2. Либо переключитесь на использование foreach для перебора массива, либо используйте continue для пропуска . и ...

user1191247 16.04.2024 10:26

Вы правы, я этого не заметил. Спасибо @user1191247. Вы случайно не знаете, как точно преобразовать цикл for в цикл foreach в PHP?

KleiaTMT 16.04.2024 10:45

Просто измените for($s = 2; $s<count($scanf); $s++){ на foreach($scanf as $file){, а затем используйте $file вместо $scanf[$s].

user1191247 16.04.2024 11:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
10
102
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Возможно, вы рассмотрите возможность использования recursiveIterator вместо рекурсивной функции — она позволит легко перемещаться по иерархии папок и предоставлять доступ к имени файла/пути к файлу. Я собрал функцию, использующую рекурсивный итератор, которая должна делать то, что вы надеетесь сделать. Доступ к соединению с БД осуществляется внутри функции после его объявления как global, но вы также можете добавить его в качестве второго именованного параметра в функцию insertTable.

Обратите внимание, что insert SQL по-прежнему добавляет как дату, так и значение по умолчанию download, где они могут (и, вероятно, должны) быть просто значениями по умолчанию, присвоенными столбцам в самой базе данных, где dateup может быть меткой времени (с использованием current_timestamp).

function insertToTable( $dir=false ){
    if ( !realpath( $dir ) )return false;
    
    # declare global variable (or include as a function parameter)
    global $conn;
    
    # basic sql cmds for use in "prepared statements"
    $sql=(object)array(
        'select'=>'SELECT * FROM `files` WHERE `name`=?',
        'insert'=>'INSERT INTO `files` ( `name`, `ftype`, `dateup`, `size`, `downloads`, `dirGroup` ) VALUES (?,?,now(),?,0,?)'
    );
    # create the prepared statements
    $stmts=(object)array(
        'select'=>$conn->prepare($sql->select),
        'insert'=>$conn->prepare($sql->insert)
    );
    # bind placeholders to variables (variables created later)
    $stmts->select->bind_param('s',$name);
    $stmts->insert->bind_param('ssss',$name,$type,$size,$folder);
    
    # counter variable for info
    $counter=0;

    # create the recursiveIterators & scan the directory
    $dirItr=new RecursiveDirectoryIterator( $dir, RecursiveDirectoryIterator::KEY_AS_PATHNAME );
    $recItr=new RecursiveIteratorIterator( $dirItr, RecursiveIteratorIterator::CHILD_FIRST );

    # iterate through scan results
    foreach( $recItr as $obj => $entity ) {
        # process files only
        if ( $entity->isFile() ){
            $type  = pathinfo( $entity->getPathName(), PATHINFO_EXTENSION );
            $name  = pathinfo( $entity->getPathName(), PATHINFO_FILENAME );
            $folder= realpath( pathinfo( $entity->getPathName(), PATHINFO_DIRNAME ) );
            $size=filesize( $entity->getPathName() );
            
            # query db to see if file already exists
            $stmts->select->execute();
            $stmts->select->store_result();
            
            # If file does not exist in db, add it.
            if ( $stmts->select->num_rows==0 ){
                $stmts->insert->execute();
                $counter++;
                printf('Adding: %s to db<br>',$name);
            }
            $stmts->select->free_result();
        }
    }
    # close statement objects
    $stmts->select->close();
    $stmts->insert->close();
    
    # leave db open if other tasks are to follow
    # otherwise call $conn->close() and return.
    return $counter ? sprintf('Scan finished: %d files processed', $counter ) : 'Scan completed: No new files added';
}



$dir=__DIR__ . '/uploads';

print insertToTable( $dir );

Спасибо за это, глядя на этот код, я действительно вспоминаю, как много я еще не знаю о PHP.

KleiaTMT 17.04.2024 02:40

Я считаю, что пробелы в этом фрагменте необычны.

mickmackusa 22.04.2024 03:11

@mickmackusa ? в каком смысле?

Professor Abronsius 22.04.2024 07:35

Раньше я не замечал, чтобы вы использовали непоследовательный интервал. Вы собрали этот ответ вместе, используя части кода от разных авторов? Я также не припомню, чтобы вы использовали так много встроенных комментариев, похожих на ИИ.

mickmackusa 22.04.2024 09:18

@mickmackusa - абсолютно НЕТ. Это на 100% мой собственный код, и я НИКОГДА не использую ИИ для составления ответов. Честно говоря, я считаю этот комментарий весьма оскорбительным и уж точно бесполезным. Возможно, есть несоответствия в интервалах, но это все равно целиком из-за моей небрежности в их форматировании.

Professor Abronsius 22.04.2024 09:35

Я не уверен, почему вас оскорбили мои наблюдения. Вы видите то же, что и я, верно? Это не атака — это наблюдение за неожиданным стилем написания статьи профессора Абронсиуса. Я не отметил этот пост ни по какой причине. Строка realpath имеет чрезмерный интервал (как в сценарии Wordpress), тогда объявления $stmts и вызовы методов вообще не имеют пробелов. В моем комментарии ни разу не утверждалось, что ваш ответ был сгенерирован ИИ; Я сказал, что встроенные комментарии выглядели так же, как выглядят многие объясненные сценарии ИИ.

mickmackusa 23.04.2024 00:03

Другие вопросы по теме