Why not checking if template file really exists in ZF2? - php

In ZF 2.2.5 Zend\View\Renderer\PhpRenderer::render method there is an if statement that checks if template exists in template stack (line 497)
$this->__file = $this->resolver($this->__template);
if (!$this->__file) {
throw new Exception\RuntimeException(sprintf(
'%s: Unable to render template "%s"; resolver could not resolve to a file',
__METHOD__,
$this->__template
));
}
try {
ob_start();
include $this->__file;
$this->__content = ob_get_clean();
} catch (\Exception $ex) {
ob_end_clean();
throw $ex;
}
But it doesn't check if file really exists in file system. Which means that subsequent try { ... } catch(\Exception $ex) {...} block is useless, because include $this->__file; is uncatchable. So when I test my controllers I always get 200 response even if template file is missing and there is nothing but exception call stack on the screen. Shouldn't that if (!$this->__file) { ... } be rewritten to if (!is_file($this->__file)) { ... }?

Well, it's up to the resolver to perform these checks. See the following code taken from Zend\View\Resolver\TemplatePathStack:
foreach ($this->paths as $path) {
$file = new SplFileInfo($path . $name);
if ($file->isReadable()) {
// Found! Return it.
if (($filePath = $file->getRealPath()) === false && substr($path, 0, 7) === 'phar://') {
// Do not try to expand phar paths (realpath + phars == fail)
$filePath = $path . $name;
if (!file_exists($filePath)) {
break;
}
}
if ($this->useStreamWrapper()) {
// If using a stream wrapper, prepend the spec to the path
$filePath = 'zend.view://' . $filePath;
}
return $filePath;
}
}
Also note that include accepts more than is_file checks for. For instance, include also accepts stream wrappers.

Related

Check if the files have been uploaded to server with php slim 3

Hi have the following code in slim to save file
I want to make sure the files have been uploaded to the server and only then to return true. or false
how can I do that with Slim or PHP?
Result of file log always null for nonreason and the file are being uploaded
public function saveFiles(Array $files, $location) {
try
{
/** #var UploadedFileInterface $file */
foreach ($files as $file) {
$fileLog = $file->moveTo($location . DIRECTORY_SEPARATOR . $file->getFilename());
}
return true;
}
catch(\Exception $e) {
throw new Exception($e->getMessage());
According to slim implementaion of this PSR, it always throws exception if something went wrong while file is being uploaded.
I don't know whether you throw another Exception for a reason, but you can process it something like:
public function saveFiles(Array $files, $location) {
$result = true;
foreach ($files as $file) {
try {
$fileLog = $file->moveTo($location . DIRECTORY_SEPARATOR . $file->getFilename());
} catch(\Exception $e) {
// Exception on file uploading happened, but
// we still continue loading other files
$result = false;
// Or just `return false;` if you don't want
// to upload other files if exception happened
// return false;
}
}
return $result;
}
Of course, this method can be extended to collect exceptions' messages and return them.

PHP Goutte try and retry

I need to crawl some data from a website. Some of the reasons for the target server, some crawl can not succeed, need to retry.The code is as follows:
private function fetchArchive($id) {
$url = 'xxxx/' . $id;
$attempt = 0;
$base = null;
if (Goutte::request('GET', $url)->filter('#table')->count() < 1) {
do {
try {
$base = Goutte::request('GET', $url)->filter('#table')->text();
} catch (InvalidArgumentException $e) {
$attempt++;
sleep(2);
break;
}
} while ($attempt <= 5);
}
In fact try($base = Goutte::request('GET', $url)->filter('#table')->text()) does not work and I recieve
"production.ERROR: InvalidArgumentException: The current node list is empty."
how do I fixed this?
Try to use \InvalidArgumentException (from the root namespace, yes).
Also consider to retry on the HTTP level, using a Guzzle's middleware (like in this example). It's better, because you handle exactly HTTP related errors in this case.
Because I used Laravel, so:
catch (\InvalidArgumentException $e) {...}

Laravel: The abort() helper ignored in the catch block

I'm trying to throw a 404 page if a file that's supposed to be downloaded doesn't exist:
try {
$fileContents = file_get_contents($url);
if ($fileContents === false) {
abort(404);
}
} catch (\Exception $e) {
abort(404);
}
Thing is, that if the file under the specified $url is missing, an exception is thrown and the execution lands in the catch block - which is fine. However, the abort(404) doesn't happen at all. Instead, a blank page is served.
Why is the abort() ignored? I can put a die('foo') in the catch and it will be echoed out.
Note - the abort() helper source:
function abort($code, $message = '', array $headers = [])
{
return app()->abort($code, $message, $headers);
}
I tested this and it works as expected. Check if you have any custom 404 error page that's resulting in the blank page or if you have any custom exception handlers set.
try {
$fileContents = file_get_contents($url);
if ($fileContents === false) {
throw new \Exception;
}
} catch (\Exception $e) {
abort(404);
}

Try/catch VS fopen (to check valid file's URL)

Hi there I want to check error-handling for an external URL (film/images) to know it is valid or not.(in my server)
I Found 2 methods:
First: try-catch method
try {
$path = savePic(...);
}
catch (MalformedURLException e) {
// exception handler code here
// ...
}
Or something like this:
if($file = fopen ($url, "rb")
{
$path = savePic($file);
}
else
{
// URL is invalid
}
Which one is better and faster for a large file?
Is there a better method to do it?
}

Error Handling with files in PHP

Error Handling with files in PHP
$path = '/home/test/files/test.csv';
fopen($path, 'w')
Here I want add an error handling by throwing exceptions, on 'No file or directory is found' and 'No permission to create a file'.
I am using Zend Framework.
By using fopen with write mode, I can create a file. But how to handle it when corresponding folder is not there?
i.e if files folder is not present in root structure.
How to throw an exception when no permission is permitted for creating a file?
Something like this should get you started.
function createFile($filePath)
{
$basePath = dirname($filePath);
if (!is_dir($basePath)) {
throw new Exception($basePath.' is an existing directory');
}
if (!is_writeable($filePath) {
throw new Exception('can not write file to '.$filePath);
}
touch($filePath);
}
Then to call
try {
createFile('path/to/file.csv');
} catch(Exception $e) {
echo $e->getMessage();
}
I suggest, you take a look at this link: http://www.w3schools.com/php/php_ref_filesystem.asp
especially the methods file_exists and is_writable
Like this:
try
{
$path = '/home/test/files/test.csv';
fopen($path, 'w')
}
catch (Exception $e)
{
echo $e;
}
PHP will echo whatever error would arise there.
Though you can also use is_dir or is_writable functions to see if folder exists and has permission respectively:
is_dir(dirname($path)) or die('folder doesnt exist');
is_writable(dirname($path)) or die('folder doesnt have write permission set');
// your rest of the code here now...
But how to handle it when corresponding folder is not there?
When a folder does not exist .. try to create it!
$dir = dirname($file);
if (!is_dir($dir)) {
if (false === #mkdir($dir, 0777, true)) {
throw new \RuntimeException(sprintf('Unable to create the %s directory', $dir));
}
} elseif (!is_writable($dir)) {
throw new \RuntimeException(sprintf('Unable to write in the %s directory', $dir));
}
// ... using file_put_contents!

Categories