2

I have got a PHP script that searches the current directory for MP3 files. I want to be able to get the metadata on the file and assign that to variables.

I am currently trying to use the Mp3Info library but it's complaining when I create an instance of it with a line that says

Undefined type 'wapmorgan\Mp3Info\Mp3Info'

How can I get this working?

<?php
use wapmorgan\Mp3Info\Mp3Info;

/* Scan dir for files */
$files = glob("*.mp3"); // all files ending with mp3.

/* sort files according to their upload time. */
usort($files, 
  function ($a, $b) {
    return filemtime($a) < filemtime($b);
  }
);

for ($i = 0; $i < sizeof($files); $i++) {
  $trackName = basename($files[$i]);
  // echo $trackName . "** **";

  // create path string for the current file
  $songPath = './';
  $songPath .= $trackName;
  // echo $songPath;

  $track = new Mp3Info($songPath, true); // MY PROBLEM SEEMS TO BE APPEARING HERE

  echo $track;

  /* Insert data into db after creating variables here */
}
AmigoJack
  • 5,234
  • 1
  • 15
  • 31
Klem Lloyd Mwenya
  • 388
  • 1
  • 6
  • 17
  • For the "will update later" part, it's perhaps right you do this right now, at least on the level of the question. If the code in your question would not contain any database code, it would be much more clear (and the problem you have obviously is not with the database, right? therefore no such code must be in the question at all ...). This would also greatly improve readability (and you can remove such comments) and therefore might produce better feedback on SO. Compare [help], you can [edit]. – hakre Jul 23 '22 at 22:28
  • Okay, let me quickly clean it up! – Klem Lloyd Mwenya Jul 23 '22 at 22:59
  • undefined type error means in your case of ǹew` that what follows as a name can not be resolved to a class definition. double check this is the correct class name (alias). – hakre Jul 24 '22 at 00:42
  • I'm surprised this Q has 2 upvotes, since the problems are simply lacking basics, while the 3rd party software is not the culprit. – AmigoJack Jul 24 '22 at 16:03

1 Answers1

0

Welcome to PHP.

Error/warning/info messages

Just like other scripting/programming languages in PHP you almost always also get a line number to seek to instead of a textual message only, so you don't have to guess where the issue occured. In the case of

<?php

use wapmorgan\Mp3Info\Mp3Info;
new Mp3Info( 'music.mp3' );

...you get a very distinctive message:

Fatal error: Uncaught Error: Class 'wapmorgan\Mp3Info\Mp3Info' not found in example.php:4
Stack trace:
#0 {main}
  thrown in example.php on line 4

Do you spot your script filename, followed by a colon and the number 4? Both times? It's the line number. The message even says so in the stack trace. Of course: read error/warning/info messages in its original and not interpreted by your web browser as HTML. In other words: press Ctrl+U to see more linebreaks.

See more at PHP Manual > Language Reference > Errors: Basics.

(Source) File inclusion

Just like other scripting/programming languages external declarations aren't magically included into your code - you have to tell so by via include or require. You haven't done so, which is why Mp3Info cannot be resolved by PHP. The correct code would be:

<?php

require( './Mp3Info.php' );  // Include _Mp3Info_'s source file with its declarations
use wapmorgan\Mp3Info\Mp3Info;
new Mp3Info( './music.mp3' );

Now there's no error anymore in your code. Of course: Mp3Info can still cause/throw errors, f.e. when the given file doesn't exist.

Data types

Just like other scripting/programming languages PHP knows different data types, f.e. string, array and object. Likewise you cannot use every possible combination of data type and function. Mp3Info's constructor will not return a string - it will return an object. Creating an instance of a class will always result in an object.

echo is meant for data types that can be converted into string (such as int and float and boolean). But an object cannot be converted into string, so using echo $object will yield an error. You need to look for something else:

  • use print_r() to print all properties of the object at once, or
  • use one of the object's property, because that can be converted to string and then used in echo (or print).

Complete working example

<?php

require( './Mp3Info.php' );  // Wherever that source file resides
use wapmorgan\Mp3Info\Mp3Info;

$obj= new Mp3Info( './music.mp3', TRUE );  // Also parse tag frames

// Print all object properties at once. Don't interpret as HTML.
header( 'Content-Type: text/plain' );
print_r( $obj );

// Print one chosen property's value only.
print( $obj-> tags['song'] );

Mp3Info

That's a questionable class/library - just search for need to to see what it misses. It will also only expect ID3v1 and ID3v2 tags in an MP3 files - not in other files and no other metadata as well. Which is by far not complete: see ID3 Parser and Editor and Where is the ID3v2 documentation?. Although not being perfect either, I recommend trying getID3, which supports much more in any way.

AmigoJack
  • 5,234
  • 1
  • 15
  • 31
  • I tested Mp3Info package to retrieve duration time but it shows wrong value on some mp3 files. (There is opened issue about this matter on it's GitHub page) – Kranchi Mar 01 '23 at 16:10
  • [I'm not surprised: it doesn't support VBR at all](https://github.com/wapmorgan/Mp3Info/blob/master/src/Mp3Info.php#L323). I discourage using this sloppy software. – AmigoJack Mar 01 '23 at 16:52
  • I switched to https://github.com/PHP-FFMpeg/PHP-FFMpeg and seems flawless. – Kranchi Mar 02 '23 at 08:44