Issue with get_file_contents and scope in PHP - php

When I'm developing websites, I use a very (very) simple system of creating pages:
//$_page is, of course, declared above the loop, just as $needed_modules is.
foreach ($needed_modules as $part)
{
global $_page;
if (file_exists($part)) {
$_page . file_get_contents($part);
} else {
//404
}
}
echo $_page;
Now, the problem is that file_get_contents doesn't return anything: not false, not a string, nada (and the file is not empty).
Execution does go inside the if and $part (which corresponds to a filename with relative path) isn't just set, but it actually points to the file.
Why is it that $_page is empty (as opposed to being set, isset($_page) actually evaluates to TRUE)?
Edit: Error-reporting is on full throttle on my server, and the logs show nothing out of the ordinary.

You are not saving the return value of file_get_contents:
$_page . file_get_contents($part);
I think you meant to say:
$_page .= file_get_contents($part);

You're not doing anything with the returned value. Try this:
$_page .= file_get_contents($part);

Related

PHP script stops before final echo

I am trainee, learning PHP. As a small project I wrote some code.
I am trying to make a (test) website about cars. I want to show that each car has several options. I have a database in MySQL.
I wrote (this is just a part of the code):
foreach ($key['options'] as $options) {
$contents = str_replace("[OPTION]",$options['text'], $contents);
}
$result= '';
foreach ($key['motor'] as $motor) {
$nm = $motor['name'];
$cnt = $motor['count'];
$result .= $cnt ." " .$nm. " ";
}
return $result;
$paginas .= $contents;
echo $paginas;
So far the code. The thing is, after the result code, the script stops (which is normal).
But I don't want that the script stops, the only thing I want is that the final echo also echo's all my return $result options PLUS the echo of '$paginas'.
It is a bit hard to explain maybe, but I hope you guys understand.
Have you read the documentation of the return statement?
return returns program control to the calling module. Execution resumes at the expression following the called module's invocation.
If called from within a function, the return statement immediately ends execution of the current function, and returns its argument as the value of the function call. return also ends the execution of an eval() statement or script file.
If called from the global scope, then execution of the current script file is ended. If the current script file was included or required, then control is passed back to the calling file.
No matter where it is used, it transfers the control to a different part of the code. The statement(s) following the return statement in the current context are not executed.
I edited the code to echo instead of return. That works.
I made blocks on the website where the information about the car is shown. 1 block per car
The thing is with the $result echo: Now I do not get a list of all different options in 1 block, but I get for every option a new 'block'. so for example:
Block: Steeringwheel. Block:Headlights. Block: Engine type
My goal is to get all these things into 1 block.

PHP file_get_contents is asynchronous?

I read that file_get_content is synchronous, but when I tried the code below I dont' think so :
$url = "http://foo.com";
$a = array("file11.php", "file2.php", "file3.php");
foreach ($a as $file)
{
$final = $url . "/" . $file;
print "Calling $final ...";
$res = file_get_contents($final);
if ($res)
print "OK";
else
print "ERR!";
print "<br>";
}
Each file executes some complex tasks, so I know the minimal excution time of any script, but this code runs very fastly and seems not to wait each request ! How can I wait for each file request?
Thanks :)
The above code is definitely synchronous. So if you say that the code exits after a few seconds, while it should be a lot longer, then you probably have a problem with the code.
Try to wrap this code in a try {} catch. And print the error. See what it says.
Try { code here } catch (Exception $e) { }
Also, most default settings in the php.ini for MAX_EXECUTION for a script is 30 seconds. After that it will exit on a fatal timeout error too. Check the setting in your php.ini and adjust it to your needs.
Edit:
Gathering your comments, I now assume you are trying to execute the php files you are referring to. This makes your question very confusing and the tags just wrong.
The code you use in your example only reads the contents of the file, so it's not executing anything. Which explains why it returns so fast, while you expect it to take a while.
If you want to execute the referred php files, approach it like this:
Include_once( $final );
Instead of opening the contents.

Trouble calling a variable from another .php file

Similar questions have been asked before, but after following several working examples closely I cannot get this to work for me.
I am trying to access the variable $nameValues that was declared in insert-name.php
insert-name.php is the first script that runs:
error_reporting(-1);
$nameValues = "'".implode("', '", array_values($nameArray))."'";
print_r($nameValues); // returns the expected variable
and insert-answer.php is the second script to run:
error_reporting(-1);
require "insert-name.php";
if (isset($nameValues)) {
print_r("nameValues variable:" . $nameValues);
} else {
echo "variable nameValues does not exist";
}
//returns nameValues variable:'' indicating that $nameValues exists but is empty
Both .php files are stored in the same folder on my webserver. I've tried using both require and include statements. I successfully use a require statement to connect to my database in both scripts, not sure why it is not working for insert-name.php.
Edit:
No errors are reported.
If statement returns "nameValues variable:'' " indicates that $nameValues variable exists but is empty.
I also tried replacing require "insert-name.php"; with require __DIR__."/insert-name.php"; which returned "variable nameValues does not exist" from the if statement.
Because neither gave a fatal error bothrequire statements successfully accessed the insert-name.php file, but I don't know why one method thinks $nameValues doesn't exist and the other thinks $nameValues is empty.
There is no problem accessing the variables from another file like you have provided they are in the same scope (one is not inside a function etc.). In your case it looks like it is just a case of how you are calling print_r()
When you do print_r('nameValues variable:" . $nameValues) you are converting $nameValues into a string.
Try something like this to dump your $nameValues:
error_reporting(-1);
require "insert-name.php";
if (isset($nameValues)) {
echo "nameValues variable: ";
print_r($nameValues);
} else {
echo "variable nameValues does not exist";
}
As you said:
returns nameValues variable:''
There was one detail I overlooked, the quotation marks at the end. When you echo a string in PHP it only prints the content (there are no quotations printed, unless they are in the string).
Effectively this all just means that $nameArray is empty, so check the script that generates this. Also, because of how implode() works, array_values() is completely redundant here.
As simple way to test this is echo count($nameArray);. If the output is "0" the array is empty.

Logging recursively

I am trying to use my logger to dump variables to my logfile.
I need it to write down arrays within arrays.
Could you explain please how to do this ? (I am not sure of how to pass the sub-array of the rest of the array but here's what I came up with, which obviously is missing something)
Thanks
function logRec($param)
{
if(!isset($param))
return;
foreach($param as $key=>$value)
{
if(is_array($value))
{
echo "<b>nested array</b><br />";
logRec(next($param));
}
else
{
echo $param;
return;
}
}
}
$par = array("ABC","DEF",array("Apple","Peach","Melon",array("Cube","Sphere","Pyramid")));
logRec($par);
I would just do this:
write_to_log_or_whatever(print_r($par, true));
The second parameter on print_r() sets it to return the output, rather than sending it to the buffer as usual.
If seeing it on too many lines isn't good for your log file, the other thing you can do is json_encode() it, but then you have to decide if having JSON-encoded data in your log is helpful. If you are going through your logs manually, it can be. But, if you have log file analysis tools, it often is a pain.

Would it be wrong if "file_exists" was designed to return a path instead of TRUE?

The file_exists function returns TRUE on success but I think it would be more useful if instead of just TRUE, it returned the value of the passed $filename. Am I wrong to think that?
If the function was designed like that, we would be able to use:
$file = file_exists("dir/file.ext");
if($file)
{
// do something
}
... instead of the more complicated:
$file = "dir/file.ext";
$success = file_exists("dir/file.ext");
if($success)
{
// do something
}
I don't see why that would be an improvement. Consider that:
In practice you will put the file_exists call inside the condition, thus there will be no extra $success variable
The name file_exists predisposes the reader of the code that the function will return a yes/no answer (boolean value)
So in conclusion, I think that it would be a bad idea to change nothing but the type of the return value.
file_exists? is basically a yes or no question, so it gives a yes or no (boolean) answer.
Does the file exist? "Yes", it exists.
So it's aptly named for what it does
That would just make no sense. It could also return the file permissions, the file size, the last modified date, and still it would make as much sense as the filename. It is nothing but a check that gives a Boolean value, and you can make decisions based on it.
By the way, I don't get your examples, what could be easier than:
$file = "dir/file.ext";
if(file_exists($file))
{
// do something with $file
}
Or if you really need the return value later, you could do:
$file = "dir/file.ext";
if($success=file_exists($file))
{
// do something with $file
}
Well, nothing really prevents you from writing this function:
function get_filename_if_exists($fname) {
return (file_exists($fname) ? $fname : FALSE );
}
It is IMHO problematic as it has multiple return types, and doesn't give you any more information than you'd get from file_exists() - and therefore worse than pointless; but it is possible to shoot yourself in the foot like this, if you really want.
(this behavior is unlikely to get retrofitted into file_exists(), for the reasons stated here and in the other answers)
Then what would be the use of fopen?
$res = fopen("my/path.txt");
if ($res===FALSE) {
// File does not exists or an error while opening
}
If you specifically want to know whether a file exists then the file_exists function does what it is supposed to do.
if (FALSE===file_exists("my/path.txt")) {
// Stop here,
}

Categories