-
-
Notifications
You must be signed in to change notification settings - Fork 159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Safe\fgetcsv throws Exception when csv file ends with a new line #361
Comments
this is definitely not intended, the exception should only trigger if the base function would return false. |
Yes i get a FilesystemException (An error occured). The base returns with false in the 3. row (PHP 8.1) |
If the base function returns false then it is normal than the safe function return an exception. I don't know why you have an error but it doesn't come from safe. |
Ok Thank you! |
@Kharhamel How are we supposed to read a csv using Safe ? while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
// ...
} I tried using while (!feof($handle)) {
$data = \Safe\fgetcsv($handle, 1000, ",");
// ...
} But with a final "\n" in csv file, which is something definitely pretty common, How can we safely detect we are at the end of the file to get out of the while loop before exception ? |
Also resolution proposed in #325 is absolutely nonsensical to me. What would be the point of using a Safe function if the ONLY way to use it, is about muting and canceling the benefit it provide ? |
I hit this problem also and having to use the workaround is ridiculous. The expected behaviour of |
But how do we know if there is an error without checking if the return is false? |
According to the doc (https://www.php.net/manual/en/function.fgetcsv.php):
So i guess this should be the proper way to do it. |
This only concerns blank line (like in the middle on the file) not trailing newline.
Checking Here is a possible implementation that would satisfy either the original behavior of function fgetcsv($stream, int $length = null, string $separator = ",", string $enclosure = "\"", string $escape = "\\"): ?array|false
{
error_clear_last();
$safeResult = \fgetcsv(...func_get_args());
if ($safeResult === false && feof($stream) === false) {
throw FilesystemException::createFromPhpError();
}
return $safeResult;
} Alternatively a specific exception can also be thrown function fgetcsv($stream, int $length = null, string $separator = ",", string $enclosure = "\"", string $escape = "\\"): ?array
{
error_clear_last();
$safeResult = \fgetcsv(...func_get_args());
if ($safeResult === false) {
if (feof($stream)) {
throw FilesystemEOFException();
}
throw FilesystemException::createFromPhpError();
}
return $safeResult;
} This way would allow us to catch and ignore FilesystemEOFException while still letting FilesystemException bubbling up if any. To reduce breaking change, FilesystemEOFException can extends FilesystemException. So you'll remain 100% backward compatible. *EOFException is a naming coming from java land. |
I got the same problem here, I guess we should use the @pyrou solution to resolve this. |
@pyrou I think I prefer the first solution since it doesn't require users to learn a new behavior. Working on it. |
Do you think there are other functions that might have the same issue? |
fgets is a similar case. Btw php.net example for fgets confirms reading foef after getting false was the right implementation :) |
The fix was deployed in version 2.3, I will do a MR later for fgets |
closing as it seems fgetcsv is handled, and we have #189 for fgets |
When iterating over a file we get an Exception if the last line is empty. Is this intended?
The text was updated successfully, but these errors were encountered: