0

The following code reads a directory containing .mp3 files and gets their tag information such as Title, Genre etc and stores these in the WAMP database, however because its reading a directory and storing the files in an array, the values in the database are being shown as "array" for every column field but I want the values for each file to show. Does anyone know how I can correct my code in order for this to happen, thanks!

my code:

$sDir = 'mp3/';
$aFiles = array();
$rDir = opendir($sDir);
if ($rDir) {
    while ($sFile = readdir($rDir)) {
        if ($sFile == '.' or $sFile == '..' or !is_file($sDir . $sFile))
            continue;

        $aPathInfo = pathinfo($sFile);
        $sExt = strtolower($aPathInfo['extension']);
        if ($sExt == 'mp3') {
            $aFiles[] = $sDir . $sFile;
        }
    }
    closedir($rDir);
}

// new object of our ID3TagsReader class
$oReader = new ID3TagsReader();

// passing through located files ..
$sList = $sList2 = '';
foreach ($aFiles as $sSingleFile) {
    $Title = $oReader->getTagsInfo($sSingleFile); // obtaining ID3 tags info
    $Author = $oReader->getTagsInfo($sSingleFile);
    $AlbumAuthor = $oReader->getTagsInfo($sSingleFile);
    $Year = $oReader->getTagsInfo($sSingleFile);
    $Genre = $oReader->getTagsInfo($sSingleFile);


    $sList .= '<tr><td>'.$Title['Title'].'</td><td>'.$Author['Author'].'</td><td>'.$AlbumAuthor['AlbumAuthor'].'</td>
                <td>'.$Year['Year'].'</td><td>'.$Genre['Genre'].'</td></tr>';



$dbhost = "localhost";
$dbname = "project";
$dbusername = "root";
$dbpassword = "";

$link = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbusername, $dbpassword);

$statement = $link->prepare("INSERT INTO mp3(Title, Author, AlbumAuthor, Year, Genre)
VALUES(:Title, :Author, :AlbumAuthor, :Year, :Genre)");
$statement->execute(array(
"Title" => "$Title",
"Author" => "$Author",
"AlbumAuthor" => "$AlbumAuthor",
"Year" => "$Year",
"Genre" => "$Genre"
));
  • show you current query and expected query – Paritosh Mahale Mar 19 '18 at 12:14
  • Where is your query? – SRK Mar 19 '18 at 12:15
  • updated it, see the above code – gurps singh Mar 19 '18 at 12:16
  • Your script is wide open to [SQL Injection Attack](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) Even [if you are escaping inputs, its not safe!](http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) Use [prepared parameterized statements](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php) – RiggsFolly Mar 19 '18 at 12:47
  • @RiggsFolly I used your edited version, it still inputs values as "Array" in my database – gurps singh Mar 20 '18 at 14:50

1 Answers1

0

You will probably find that calling ->getTagsInfo() returns an array of all the tag details. You can verify this by doing

print_r($Title);

Reading the example code on https://www.script-tutorials.com/id3-tags-reader-with-php/ and assuming a similar process, they have code which does -

$aTags = $oReader->getTagsInfo($sSingleFile); // obtaining ID3 tags info
$sList .= '<tr><td>'.$aTags['Title'].'</td><td>'.$aTags['Album'].'</td><td>'.$aTags['Author'].'</td>

So the important part here is that $aTags is a list of all of the tags and the second line uses $aTags['Title'] to get the title.

So you probably need to replace your code with...

$dbhost = "localhost";
$dbname = "project";
$dbusername = "root";
$dbpassword = "";

$link = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbusername, $dbpassword);

$statement = $link->prepare("INSERT INTO mp3(Title, Author, AlbumAuthor, Year, Genre)
VALUES(:Title, :Author, :AlbumAuthor, :Year, :Genre)");
foreach ($aFiles as $sSingleFile) {
    $aTags = $oReader->getTagsInfo($sSingleFile); 
    $Title = $aTags['Title'];
    $Author = $aTags['Author'];
    $AlbumAuthor = $aTags['AlbumAuthor'];
    $Year = $aTags['Year'];
    $Genre = $aTags['Genre'];
    $sList .= '<tr><td>'.$Title.'</td><td>'.$Author.'</td><td>'.$AlbumAuthor.'</td> <td>'.$Year.'</td><td>'.$Genre.'</td></tr>';

    if ( !$statement->execute(array(
            "Title" => $Title,
            "Author" => $Author,
            "AlbumAuthor" => $AlbumAuthor,
            "Year" => $Year,
            "Genre" => $Genre )))      {
        echo "Error:".print_r($link->errorInfo(),true);
    }
}
Nigel Ren
  • 56,122
  • 11
  • 43
  • 55
  • When I do that, I get this error Cannot use object of type ID3TagsReader as array in C:\wamp64\www\system\lol.php on line 35 – gurps singh Mar 20 '18 at 14:48
  • Really sorry - that was me being stupid. I've corrected the answer,should be `$aTags['Title']` etc. – Nigel Ren Mar 20 '18 at 15:20
  • appreciate you trying to help mate, really do. I'm getting this error. Warning: Illegal string offset 'Title' in C:\wamp64\www\system\lol.php on line 41 – gurps singh Mar 20 '18 at 15:44
  • with the correction made, its not outputting correct now either, really confusing me – gurps singh Mar 20 '18 at 15:45
  • Can you try `print_r($aTags);` to see what it contains. – Nigel Ren Mar 20 '18 at 15:45
  • it outputs WelcomebcdefIntroJ.B.G.Last Words which is the list of the four .mp3 title tags, this is correct. for print_r($aTags); – gurps singh Mar 20 '18 at 15:49
  • Array ( [FileName] => mp3/file1.mp3 [Version] => 3.0 [Title] => Welcomebcdef [Album] => mericanaaabcdef [Author] => gurpreet [Track] => 1 [Year] => 2000 [Genre] => Other [Comments] => offspring ) dj frenzyArray ( [FileName] => mp3/file2.mp3 [Version] => 3.0 [Title] => Intro [Album] => onspiracy [Author] => Offspring [AlbumAuthor] => dj frenzy [Track] => 7 [Year] => 2000 [Genre] => Rock [Encoded] => tr6 [Copyright] => str5 [Publisher] => str3 [OriginalArtist] => str4 [URL] => [Comments] => Offspring) – gurps singh Mar 20 '18 at 15:57
  • $sList .= ''.$Title['Title'].''.$Author['Author'].''.$AlbumAuthor['AlbumAuthor'].' '.$Year['Year'].''.$Genre['Genre'].''; – gurps singh Mar 20 '18 at 16:18
  • Ermmm... see update to answer `$Title['Title']` should just be `$Title` etc. – Nigel Ren Mar 20 '18 at 16:21
  • brilliant this works, however it is only appending the tags for one of the files in the directory as opposed to 4. why is this? – gurps singh Mar 20 '18 at 16:24
  • You mean `$sList` doesn't have all of the content? – Nigel Ren Mar 20 '18 at 16:27
  • $sList does, it displays it perfectly in the table, however when I append this data to the database it is only doing it for one record. The statement is $exec = "INSERT INTO mp3(Title, Author, AlbumAuthor, Year, Genre) VALUES('".$Title."','".$Author."','".$AlbumAuthor."','".$Year."','".$Genre."')"; – gurps singh Mar 20 '18 at 16:31
  • Check out https://stackoverflow.com/questions/18655706/pdo-with-insert-into-through-prepared-statements as prepared statements are much safer and less prone to errors. – Nigel Ren Mar 20 '18 at 16:37
  • I have edited my code above using prepared statements, still the same. It only stores the last file in the directory – gurps singh Mar 20 '18 at 16:54
  • I've updated the code example, the connect and prepare go outside the loop. The main thing I'm hoping is that if an error occurs, that you'll get some more info. I can't test this code, but hopefully it runs. – Nigel Ren Mar 20 '18 at 17:03
  • I just get Error:ArrayError:ArrayError:Array – gurps singh Mar 20 '18 at 17:11
  • Updated error line to - ` echo "Error:".print_r($link->errorInfo(),true);` – Nigel Ren Mar 20 '18 at 17:14
  • Error:Array ( [0] => 00000 [1] => [2] => ) Error:Array ( [0] => 00000 [1] => [2] => ) Error:Array ( [0] => 00000 [1] => [2] => ) – gurps singh Mar 20 '18 at 17:19
  • So there are no errors. How are you checking the database? – Nigel Ren Mar 20 '18 at 17:31
  • I'm using WAMP, however even the table results show the same record however it is shown 6 times – gurps singh Mar 20 '18 at 17:34
  • Am I able to send you the file somehow? – gurps singh Mar 20 '18 at 17:53
  • Not sure what is happening, your data is being read properly, the insert isn't getting any error. – Nigel Ren Mar 20 '18 at 18:11
  • The table of data works fine, it just doesn't append the tags for the multiple files to the database – gurps singh Mar 20 '18 at 18:12