I have php file where i use if statments and i call this file via ajax.. onSuccess it gives me result if file is upload successfully or error.
Code look like this:
if(empty($_FILES['file']['name'])){
return "no image was selected";
}
if($two_many_images){
return "Only x images are alowed to upload";
}
if($size>2014522){
return "Size error";
}
foreach($_FILES["file"]['tmp_name'] as $key=>$imgLocation){
uploadImage($_FILES["fileToUpload"]['tmp_name'][$key], $imgLocation);
}
Question : In first if statment condition is true, wil my second if statment execute ?
This can be easily demonstrated, for example you have a function:
funciton foo(){
echo "foo\n";
return;
echo 'bar';
}
if you call
foo();
It will print out
foo
But not bar. Once execution pointer hits the return it will return back to where foo() was called from. This can also be easily shown.
foo();
foo();
foo();
Prints
foo
foo
foo
UPDATE: based off your comments the correct way to do what you want is this
if(empty($_FILES['file']['name'])){
echo "no image was selected";
exit();
}
if($two_many_images){
echo "Only x images are alowed to upload";
exit();
}
if($size>2014522){
echo "Size error";
exit();
}
foreach($_FILES["file"]['tmp_name'] as $key=>$imgLocation){
uploadImage($_FILES["fileToUpload"]['tmp_name'][$key], $imgLocation);
}
I use exit() instead of return, because it's more readable and makes more sense, even though in your case return has the same effect. Exit will completely end execution for php, which is really what you want. You could also do something like
die( 'Message' );
Or
exit( 'Message' );
As well which will exit and output the message. They are all pretty much the same... I put echo first just because it always feels a bit dirty to me to put stuff in exit. Not sure why that is, maybe it I link it to unintended behavior because of seeing die() so much at the top of files not meant to be ran outside of framework. But I digress.
Just for the sake of completeness, based of your comments, if you call return from the global scope in PHP, it has no where to return to so execution just halts at that point. The reason it's better to use exit or die is that return has distinctly different behavior, which is to 'return' data from a function call. So it's more readable to use the method who's behavior best matches what you want. That being to end execution of the current script ( PHP instance ).
No, your second statement will not be executed. When the return is invoked, the rest of the code will not be executed. The PHP documentation says:
If called from the global scope, then execution of the current script file is ended.
Related
I have an extremely oversimplified logger function:
<?php
class Logger {
public function __construct($logFile) {
$this->logFile = $logFile;
}
public function log($message) {
$message = date('c') . $message;
file_put_contents($this->logFile, $message, FILE_APPEND | LOCK_EX);
echo "it ran ";
}
}
Calling it like this
$logger = new Logger('log.txt');
$logger->log("message");
echo "called the method";
causes the message to be written to the file exactly 3 times, instead of 1.
The code is outside of any loop, which is confirmed by echo statements, which get printed only once.
Also, if I simply run file_put_contents() function on place where I'd call the log method, it works fine and writes the content just once. So it might have something to do with my class, but no clue what.
EDIT: #Tommy: here is the log file content:
2014-09-26T07:24:51-04:00message2014-09-26T07:24:54-04:00message2014-09-26T07:24:54-04:00message
EDIT 2: I tried using die() function after calling the method, and then it did write the message just once. So I kept moving the die() through the code, and it starts writing the message 3 times after this exact line:
if (isset($_POST['create_account'])) {
die;
Since there's a die below it, it shouldn't even matter what's in further code, right?
Wonder if it might be some sort of php bug, this is very stange. If I put the die() above this line, it will work fine and write the message just once.
There's a fairly good chance that your code does a redirect or reload somewhere. This causes a new request to start, which wipes away the original echo but does not remove the one written to file. As a result it looks like it was echo'd once and written thrice. But really, it was echo'd thrice as well, just the other copies have been removed.
If you want to see what's going on, print part of the stack-trace into the log-file along with the message. You can see exactly on which line the message is created and during which function call.
The main issue as per my experience is the index.php is being called twice. So, to fix:
change the file name
fix the index.php such that favicon.ico is missing!
when we use return in PHP on global scope, after return, does execution just stop?
or processing will go on?
<?php
if(defined("A")) return;
define("A", true);
echo "Hello";
if(defined("A")) return;
define("A", true);
echo "Hello";
?>
If you want to stop a script, you'd better use exit, because return should be only used in functions !
http://php.net/manual/en/function.return.php
http://php.net/manual/en/function.exit.php
In your case, the script will end as said by the documentation : return will also end the execution of an eval() statement or script file
Your script will be stopped after first return
As documenation says:
If return is called from within the main script file, then script
execution ends
Is it ok to include a break or exit command to prevent further code from executing or is this bad programming?
function index()
{
$error = NULL;
if ($_POST){
// validate form
if ($form_validated) {
echo 'this content only';
exit; // or return IS THIS BAD???
} else {
$error = 'form failed';
}
}
echo 'normal page on initial load';
if ($error) { echo '<br />'.$error; }
}
It is OK to prevent further code from executing using exit.
Having said that, whether this is the best way to do it in this particular example is debatable. It is typical to use exit when issuing redirects:
header('Location: /foo');
exit;
In your case, there doesn't seem to be an immediate need to stop the program execution in mid run. You should rather structure your program flow so it always completes, but with different results. It is hard to follow program logic which may terminate somewhere in the middle, so a more logical flow that returns from functions or branches using if..else is usually preferable.
For the example you give:
function index()
{
...
if ($form_validated) {
echo 'this content only';
exit; // or return IS THIS BAD???
} else {
...
}
This is normally called early exit or early return (return is more common). This can be very okay, some people say that early returns make code hard to understand but I'd say it depends on a lot more if a function can be easily read and understood or not.
So the person who decides here whether it is bad or not is you. You need to find some criteria on your own where you draw the line. For example if a function is long (more than 12 lines of code) and contains many of these early returns or even exits, this will make the code more complicated.
Generally early returns can make a functions code less complex which can heavily reduce the number of bugs.
So probably the complexity is a good criteria here.
Additionally I suggest you use exit very carefully. It does much at once and you should normally not need it within your program flow. Especially if you're writing business logic.
Is it a good or bad practice to authenticate and then just exit() the function or to wrap the whole result of the authentication in an if statement? Example
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == false) exit();
//continue with senstive code here
}
}
OR
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == true)
{
// do sensitive stuff
}
}
I would like to take this opportunity to talk about exit; (as others have stated both work, the second is more explicit then the first, and give you the opportunity to send a nice error message to the user). My main beef (I have several with exit;) is that people should stop using it in libraries, i.e. code that can/will be used in other projects... You know how irritating it is to debug those? Throw exceptions, trigger fatal errors, but give me something with a description.
/rant
Your examples are equivalent.
However, it's not usually useful to the end user to just exit the script abruptly. Instead, send your user a useful error message printed in HTML rather than the plain text you would get from a die() call, for example.
function foo($uid)
{
$allowed = $auth->checkIfAllowed($uid);
if ($allowed == false)
{
$errormsg = "You are not allowed to view this page";
}
else
{
//continue with senstive code here
}
}
Later, print the error in HTML, rather than just aborting the script:
<div class='error'><?php echo $errormsg; ?></error>
Either or. I don't think it'll make a difference. It relatively the exact same thing. In programming there are many ways to program things, never on right way in most instances.
They are absolutely the same. The indentation and coding style is the only difference. In both cases the sensitive code won't execute unless the authentication is done successfully.
It's usually better to be expressive in your code though, so I'd recommend the second method.
I have a simple function1 that does a http request to a google api and returns the $result.
I then have another function2 that, if $result isset, should use $result to do some computing and then return $finalresult. .
My problem is that the call to the google api takes a couple of seconds and by the time $result is returned by function1, function2 has already returned $finalresult without taking into consideration $result.
What I am looking to do is to have function1 to run completely and return $result before function2 even begins.
Preferrably I am looking for a solution that is not simply using "sleep()" as this function will not guarantee that $result is actually returned. (Unless there is some way to loop a sleep(1) until $return isset, or something like that)
Sample code for the visual gals and guys
function1_geocode($address); // this function makes a http request to google and returns $result
function2_proximitysearch(){
if (isset($result)){
//inevitably by the time the script gets there, $result hasn't been returned yet therefore none of the "some stuff" code is executed.
//some stuff
}
else {
//some other stuff
}
}
PHP is not asynchronous. Functions are executed one after another.
why don't you have function 1 call function 2 when it is done?
additionally, Mchl is right. function 1 will have to complete before the code executes function 2. Maybe you should set up your code like so:
$foo = 0;
$foo = function1();
if($foo > 0)
function2();
function1()
{
if($something)
$foo = 1;
}
function2()
{
$something = $else;
}
That way it will only call function 2 if function 1 changed the value of $foo.
Of you could post your full code and we'll know what you're trying to do.
PHP isn't threaded, so if you call function1_geocode before function2_proximitysearch, $result should always be set.
It could be that function1_geocode($address) has a bug, or else you might be missing some documentation for how that function is used.
It's possible to kinda simulate asynchronous functionality by, for example saving results in a file to be dealt with by a second page load. But that would have to be specifically designed that way. Within one PHP page load, you can't have a process running in the background.