0

I am trying to read a file ($txtFile) line-by-line. Then store the different items in the line ($line) separated by comma in an array ($pieces). The code is given below.

 <?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>

But I am getting the following error:

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

I am using PHP-7.0 & I am unable to understand what's wrong with this code. How do I get rid of this error?

8
  • do a print_r($pieces);. That should give you a head-start Commented Nov 8, 2018 at 9:41
  • 2
    Mind empty lines. Also consider file() or fgetcsv() and list() for such tasks. Commented Nov 8, 2018 at 9:42
  • print_r($pieces); gives Array ( [0] => ) Commented Nov 8, 2018 at 9:43
  • Are you sure all the lines contain the number of commas you expect? Commented Nov 8, 2018 at 9:44
  • Wait a minute. I am posting the complete code! Commented Nov 8, 2018 at 9:46

3 Answers 3

1

A quick fix, would be to check that you have a line with 7 elements, so after your explode, just check how many elements the array has and skip the rest of the processing if there aren't enough values...

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

You should also look into using prepared statements as the offer more security, although you will still have to do a substitution for the table name as you do now (you can't have a table name as a bind variable).

Also as a recommendation, when doing an INSERT,always list the column names ...

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

as this ensures that it's clear which column is where and if any table changes are made that the INSERT is explicit about which values it is using for which columns.

Sign up to request clarification or add additional context in comments.

12 Comments

The files are indeed empty because file_get_contents($url) isn't getting data. $url is working fine but $content is empty. Can you please tell me why is this happening?
Can you give me 1 line from the tickerMaster.txt file so I can test it.
Try adding ini_set('display_errors', 'On'); and error_reporting(E_ALL); to the start of your script, I get failed to open stream: HTTP request failed! HTTP/1.0 401 Unauthorized.
Warning: file_get_contents(https://query1.finance.yahoo.com/v7/finance/download/TSLA?period1=1538917807&period2=1541596207&interval=1d&events=history&crumb=6DH0b71wPwr): failed to open stream: HTTP request failed! HTTP/1.0 401 Unauthorized
This is the warning I am getting every time for each link
|
1

Your file contains a blank line (or possibly multiple). You'll usually see this at the very end of the file.

Because of this, explode() returns an array with a single empty value, while you expect 7 (keys 0 through 6).

Before exploding the line to an array, check if it is indeed empty. Or count the array after creating it, and validate the expected number of keys are present.

Comments

1

Before indexing into the array, you might check if the number of items in $pieces by for example counting the number if items that explode returns:

$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];
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.