Разрыв строки из файла дает ошибку неопределенного смещения в PHP - PullRequest
0 голосов
/ 08 ноября 2018

Я пытаюсь прочитать файл ($txtFile) построчно. Затем сохраните различные элементы в строке ($line), разделенные запятой в массиве ($pieces). Код приведен ниже.

 <?php
    include_once __DIR__.'/connect.php';

    function createURL($ticker)
    {
        $currentPeriod = time(); 
        return "https://query1.finance.yahoo.com/v7/finance/download/$ticker?period1=1538917807&period2=1541596207&interval=1d&events=history&crumb=6DH0b71wPwr";
    }

    function getCSVFile($url, $outputFile)
    {
        $content = file_get_contents($url);
        $content = str_replace("Date,Open,High,Low,Close,Adj Close,Volume", "", $content);
        $content = trim($content);
        file_put_contents($outputFile, $content);
    }

    function fileToDatabase($txtFile, $tableName)
    {
        $file = fopen($txtFile, "r");
        while (!feof($file)) {
            $line = fgets($file);
            $pieces = explode(",", $line);
            print_r($pieces);
            $date = $pieces[0];
            $open = $pieces[1];
            $high = $pieces[2];
            $low = $pieces[3];
            $close = $pieces[4];
            $adj_close = $pieces[5];
            $volume = $pieces[6];
            $amount_change = $adj_close-$open;
            $percent_change = ($amount_change/$open)*100;
            $sql = "SELECT * FROM $tableName";
            $result = $conn->query($sql);

            if (!$result) {
                $createQuery = "CREATE TABLE $tableName (
                    date TIMESTAMP PRIMARY KEY,
                    open FLOAT,
                    high FLOAT,
                    low FLOAT,
                    close FLOAT,
                    adj_close FLOAT,
                    volume INT,
                    amount_change FLOAT,
                    percent_change FLOAT
                )";
                $conn->query($createQuery);
            }

            $insertQuery = "INSERT INTO $tableName VALUES (
                '$date', '$open', '$high', '$low', '$close', '$adj_close', '$volume', '$amount_change', '$percent_change'
            )";
            $conn->query($insertQuery);
        }
        fclose($file);
    }

function main()
{
    $pathToTickerFile = __DIR__."/tickerMaster.txt";
    $mainTickerFile = fopen($pathToTickerFile, "r");
    while (!feof($mainTickerFile)) {
        $companyTicker = fgets($mainTickerFile);
        $companyTicker = trim($companyTicker);

        $fileURL = createURL($companyTicker);
        $companyTxtFile = __DIR__."/txtFiles/".$companyTicker.".txt";
        getCSVFile($fileURL, $companyTxtFile);
        fileToDatabase($companyTxtFile, $companyTicker);
    }
    fclose($mainTickerFile);
    echo "The stocks have been downloaded!";
}

main();

?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Stock Downloader</title>
</head>
<body>
</body>
</html>

Но я получаю следующую ошибку:

PHP Notice:  Undefined offset: 1
PHP Notice:  Undefined offset: 2
PHP Notice:  Undefined offset: 3
PHP Notice:  Undefined offset: 4
PHP Notice:  Undefined offset: 5
PHP Notice:  Undefined offset: 6

Я использую PHP-7.0 и не могу понять, что не так с этим кодом. Как мне избавиться от этой ошибки?

Ответы [ 3 ]

0 голосов
/ 08 ноября 2018

Перед индексацией в массиве вы можете проверить количество элементов в $pieces, например, посчитав число, если возвращающиеся элементы возвращаются:

$file = fopen($txtFile, "r");
while (!feof($file)) {
    $line = fgets($file);
    $pieces = explode(",", $line);
    if (count($pieces) > 6) {
        $date = $pieces[0];
        $open = $pieces[1];
        $high = $pieces[2];
        $low = $pieces[3];
        $close = $pieces[4];
        $adj_close = $pieces[5];
        $volume = $pieces[6];
    }
}
0 голосов
/ 08 ноября 2018

Быстрое решение - проверить, что у вас есть строка с 7 элементами, поэтому после разнесения просто проверьте, сколько элементов имеет массив, и пропустите остальную часть обработки, если не хватает значений ...

$pieces = explode(",", $line);
if ( count($pieces) != 7)   {
    continue;
}
$date = $pieces[0];
// ....

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

Также в качестве рекомендации при выполнении ВСТАВКИ всегда перечисляйте имена столбцов ...

INSERT INTO $tableName (date, open, ... )
   VALUES ('$date', '$open', ...)

, поскольку это гарантирует, что будет ясно, в каком столбце находится место, и если будут внесены какие-либо изменения в таблицу, то INSERT явно указывает, какие значения он использует для каких столбцов.

0 голосов
/ 08 ноября 2018

Ваш файл содержит пустую строку (или, возможно, несколько).Обычно вы увидите это в самом конце файла.

Из-за этого explode() возвращает массив с единственным пустым значением, в то время как вы ожидаете 7 (ключи от 0 до 6).

Прежде чем взорвать строку в массив, проверьте, действительно ли он пуст.Или подсчитайте массив после его создания и проверьте ожидаемое количество присутствующих ключей.

...