What is the output of the exiftool command? My guess is that you need to add some error handling.
I'm not aware of the exiftool output. Should I be logging output?
Users upload images and I run them thru exiftool. Most of the time if works, but sometimes I get the error mentionned above...
Sorry, I don't want to offend you, but to be honest you are lacking basics and you aren't reading manuals. When you'll learn about basic commands, you should learn important thing - debugging. Like other people said, we need to know what happens between commands. If you'd use var_dump(json_decode($array)); you'd have an answer why it's not gonna work.
But I wonder - how comes
sometimes it give error? In my opinion it should always show error.
json_decode($foo) returns object, not array, and you are passing that object into array function. And why would you get value of element of array pointed by internal pointer and convert is to array? That's something very weird.
And why are you checking it by empty()?
If exiftool will fail and show error message, empty() expression will evaluate to true. If that's supposed to catch errors, you should use exec() and read exit code, but well, that's the thing that's written in manual: "
It is not possible to detect execution failures using this function. exec() should be used when access to the program exit code is required."
To use array functions you need to have array. To convert string to array you need to use json_decode($foo, true). Again - manual. The second parameter is "
When TRUE, returned objects will be converted into associative arrays".
<?php $filename = escapeshellarg($filename); // you need to escape file name! $cmdOutput = null; // initialize var, because we will send pointer, so it should exist already @$cmd = exec("/usr/bin/exiftool -j {$filename}", $cmdOutput, $exitCode); // use exec, not shell_exec; the line is silenced, as we have own error handling if ($exitCode === 0) { // "The exiftool application exits with a status of 0 on success" - from ExifTool manual $cmdOutput = implode(PHP_EOL, $cmdOutput); // exec returns array exploded by PHP_EOL, so we reverse it; @$json = json_decode($cmdOutput, true); // to get array you need to use second parameter! Silenced for the same reason. if (json_last_error() === JSON_ERROR_NONE) { // check if json decoding passed // here's the code if command passed _and_ JSON decode passed } else echo json_last_error_msg(); // show last error, if occured } else echo "Command failed. The exit code: {$exitCode}." . ($cmd ? "The last line of output: {$cmd}" : ''); // error handler for exec; exit code and (if there's anything) the last line of output