Related
I have a PHP file as seen below that is a config file.
When I use return in my code and var_dump(include 'config.php');
I see an array, but when I delete return the result is
int 1
Does include work like a function in this case? And why I have to use return here?
<?php
return array(
'database'=>array(
'host'=>'localhost',
'prefix'=>'cshop_',
'database'=>'finalcshop',
'username'=>'root',
'password'=>'',
),
'site'=>array(
'path'=>'/CshopWorking',
)
);
The return value of includeis either "true"(1) or "false". If you put a return statement in the included file, the return value will be whatever you return. You can then do
$config = include config.php';
and $configwill then contain the values of the array you returned in config.php.
An include fetches PHP-code from another page and pastes it into the current page. It does not run the code, until your current page is run.
Use it like this:
config.php
$config = array(
'database'=>array(
'host'=>'localhost',
'prefix'=>'cshop_',
'database'=>'finalcshop',
'username'=>'root',
'password'=>'',
),
'site'=>array(
'path'=>'/CshopWorking',
)
);
And in your file, say index.php
include( 'config.php' );
$db = new mysqli(
$config['database']['host'],
$config['database']['username'],
$config['database']['password'],
$config['database']['database'] );
This way, you do not need to write all that stuff into every file and it is easy to change!
Here are some statements with similarities:
include - insert the file contents at that point and run it as if it were a part of the code. If the file does not exist, it will throw a warning.
require - same as include, but if the file is not found an error is thrown and the script stops
include_once - same as include, but if the file has been included before, it will not do so again. This prevents a function declared in the included file to be declared again, throwing an error.
require_once - same as include_once, but throws an eeror if the file was not found.
First off, include is not a function; it is a language construct. What that means is something you should Google for yourself.
Back to your question: what include 'foo.php does is literally insert the content of 'foo.php' into your script at that exact point.
An example to demonstrate: say you have two files, foo.php and bar.php. They look as follows:
foo.php:
<?php
echo "<br>my foo code";
include 'bar.php';
$temp = MyFunction();
bar.php:
<?php
echo "<br>my bar code";
function MyFunction()
{
echo "<br>yes I did this!";
}
This would work, because after evaluating the include statement, your foo.php looks like this (for your PHP server):
<?php
echo "<br>my foo code";
echo "<br>my bar code";
function MyFunction()
{
echo "<br>yes I did this!";
}
$temp = MyFunction();
So your output would be:
my foo code
my bar code
yes I did this!
EDIT: to clarify further, if you create variables, functions, GLOBAL defines, etc. in a file, these will ALL be available in any file in which you include that file, as if you wrote them there (because as I just explained, that is basically what PHP does).
I am trying to organize my "actions" a little bit better, currently it is a giant switch statement with a ton of cases, and it's very hard to manage. I want to move the actions into their own files that can be managed easier. But I am trying to sort through an issue.
I have a foreach loop that loops over all the "called actions" and calls them. Then I have a bunch of actions, but some actions I want to end execution of the current loop (i.e. continue; or break;) but that does not seem to be working on an included file.
Is there anyway else I could do this? I also need the "actions" to have access to all the current variables defined in the executing script (which is why I went for include).
Currently...
included_file.php
<?php
blah blah stuff
if(statement) {
// accesses variables declared in calling_file.php
continue;
}
?>
calling_file.php
<?php
blah blah stuff
// declare variables that need to be accessed in included_files.php
foreach() {
include included_file.php
}
?>
Now for some actions I want to stop the current loop and move onto the next. Any ideas?
If I understand your question properly, it appears you want to get a result from the included file that signals what you want to do (break,continue) and then a simple switch statement to allow an inner loop to break an outer loop. The break control structure will allow you to do this.
calling_file.php
<?php
$includes = array ('included_file1.php', 'included_file2.php', 'included_file3.php');
const CONTROL_BREAK = 3;
const CONTROL_CONTINUE = 7;
// declare variables that need to be accessed in included_files.php
foreach($includes as $include) {
print "Including $include\n";
$result = include($include);
switch ($result){
case CONTROL_BREAK:
break 2;
case CONTROL_CONTINUE:
default:
continue 2;
}
}
included_file1.php
<?php
print __FILE__ . " has been included!\n";
if(TRUE) {
print "I should continue!\n";
return CONTROL_CONTINUE;
}
included_file2.php
<?php
print __FILE__ . " has been included!\n";
if(TRUE) {
print "I should break!\n";
return CONTROL_BREAK;
}
included_file3.php
<?php
print __FILE__ . " has been included!\n";
if(TRUE) {
print "You should never see me!";
}
Is is possible for a php script to know if another script calls it via require or require_once?
eg:
if scripta.php calls me do xyz;
if scriptb.php calls me do abc;
Edit: Thanks for your suggestions guys. It was more of a what if question, rather than an actual problem. I realise I could set a variable, $caller and update it when I made the require statement. I just wondered if there was another way to do this in the file that's being called :)
If you just want to check if the your file was included or not:
$_SERVER['SCRIPT_FILENAME'] will always return the filename of the script that has been originally called. (e.g. "start.php")
The constant __FILE__ will always return the true file name of the script that it is used in. (e.g. "library.inc.php")
So you can do something like this:
if ($_SERVER['SCRIPT_FILENAME'] !== __FILE__) {
echo "script was included!";
}
else {
echo "script was called directly!";
}
If you want to distinguish from where the file has been included:
$include_from = get_included_files();
if (count($include_from) > 1) {
$include_from = $include_from[count($include_from)-2];
}
else {
$include_from = $include_from[0];
}
switch ($include_from) {
case __FILE__:
// not included, called directly
break;
case "/path/to/scripta.php":
// do abc
break;
case "/path/to/scriptb.php":
// do xyz
break;
default:
// do other stuff
break;
}
You can retrieve the files in the order in which they have been included via get_included_files() (returns an array of the filenames).
The main file that was executed is always the 0th element.
If you're looking for the file that included the current file, the last but one element is your candidate.
I suggest using get_included_files (or get_required_files):
if(in_array($my_file, get_included_files())
{
// do something
}
Replace $my_file with the file you need to check.
One possibility is defining constants.
Calling script:
define("SCRIPT_NAME", "script_a.php");
And in the called script:
if(defined("SCRIPT_NAME") && SCRIPT_NAME == "script_a.php") {
// Do stuff
}
You can use debug_backtrace()
Example:
If you use debug_backtrace() on an included file :
array(1) {
[0]=> array(3) {
["file"]=> string(71) "/home/index.php"
["line"]=> int(3)
["function"]=> string(7) "require"
}
}
a require is nothing else then a code snipped loaded into the exact place the require or require_once call is called.
if you really want to know what exact file is calling it, you could do it relative dirty and assign a variable before the call and check inside your script what kind of value it has
e.g.
$require_reference = "main.php";
require_once ("some_script.php");
now inside the some_script.php you do something like this:
if (isset($require_reference) && $require_reference == "main.php")
{
// dome something
}
this will work but it is really messy. Maybe you should try to refactor your design
Is there any command in PHP to stop executing the current or parent if statement, same as break or break(1) for switch/loop. For example
$arr=array('a','b');
foreach($arr as $val)
{
break;
echo "test";
}
echo "finish";
in the above code PHP will not do echo "test"; and will go to echo "finish";
I need this for if
$a="test";
if("test"==$a)
{
break;
echo "yes"; // I don't want this line or lines after to be executed, without using another if
}
echo "finish";
I want to break the if statement above and stop executing echo "yes"; or such code which is no longer necessary to be executed, there may be or may not be an additional condition, is there way to do this?
Update: Just 2 years after posting this question, I grew up, I learnt how code can be written in small chunks, why nested if's can be a code smell and how to avoid such problems in the first place by writing manageable, small functions.
Sometimes, when developing these "fancy" things are required. If we can break an if, a lot of nested ifs won't be necessary, making the code much more clean and aesthetic.
This sample code illustrates that in certain situations a breaked if can be much more suitable than a lot of ugly nested ifs.
Ugly code
if(process_x()) {
/* do a lot of other things */
if(process_y()) {
/* do a lot of other things */
if(process_z()) {
/* do a lot of other things */
/* SUCCESS */
}
else {
clean_all_processes();
}
}
else {
clean_all_processes();
}
}
else {
clean_all_processes();
}
Good looking code
do {
if( !process_x() )
{ clean_all_processes(); break; }
/* do a lot of other things */
if( !process_y() )
{ clean_all_processes(); break; }
/* do a lot of other things */
if( !process_z() )
{ clean_all_processes(); break; }
/* do a lot of other things */
/* SUCCESS */
} while (0);
As #NiematojakTomasz says, the use of goto is an alternative, the bad thing about this is you always need to define the label (point target).
Encapsulate your code in a function. You can stop executing a function with return at any time.
proper way to do this :
try{
if( !process_x() ){
throw new Exception('process_x failed');
}
/* do a lot of other things */
if( !process_y() ){
throw new Exception('process_y failed');
}
/* do a lot of other things */
if( !process_z() ){
throw new Exception('process_z failed');
}
/* do a lot of other things */
/* SUCCESS */
}catch(Exception $ex){
clean_all_processes();
}
After reading some of the comments, I realized that exception handling doesn't always makes sense for normal flow control. For normal control flow it is better to use "If else":
try{
if( process_x() && process_y() && process_z() ) {
// all processes successful
// do something
} else {
//one of the processes failed
clean_all_processes();
}
}catch(Exception ex){
// one of the processes raised an exception
clean_all_processes();
}
You can also save the process return values in variables and then check in the failure/exception blocks which process has failed.
Because you can break out of a do/while loop, let us "do" one round. With a while(false) at the end, the condition is never true and will not repeat, again.
do
{
$subjectText = trim(filter_input(INPUT_POST, 'subject'));
if(!$subjectText)
{
$smallInfo = 'Please give a subject.';
break;
}
$messageText = trim(filter_input(INPUT_POST, 'message'));
if(!$messageText)
{
$smallInfo = 'Please supply a message.';
break;
}
} while(false);
goto:
The goto operator can be used to jump to another section in the program. The target point is specified by a label followed by a colon, and the instruction is given as goto followed by the desired target label. This is not a full unrestricted goto. The target label must be within the same file and context, meaning that you cannot jump out of a function or method, nor can you jump into one. You also cannot jump into any sort of loop or switch structure. You may jump out of these, and a common use is to use a goto in place of a multi-level break...
There exist command: goto
if(smth) {
.....
.....
.....
.....
.....
goto My123;
.....
.....
}
My123:
....your code here....
BUT REMEMBER! goto should not be ever used anywhere in real-world scripts, as it is a sign of poor code.
You could use a do-while(false):
<?php
do if ($foo)
{
// Do something first...
// Shall we continue with this block, or exit now?
if ($abort_if_block) break;
// Continue doing something...
} while (false);
?>
as described in http://php.net/manual/en/control-structures.if.php#90073
No, there is no way to "break" an if block like you would inside loops.:(
So turn your test into a switch !
I wonder why nobody encouraged you to use switch statement since (even if you haven't to many test cases)
Do you think it's too verbose?
I would definitely go for it here
switch($a){
case 'test':
# do stuff here ...
if(/* Reason why you may break */){
break; # this will prevent executing "echo 'yes';" statement
}
echo 'yes'; # ...
break; # As one may already know, we might always have to break at the end of case to prevent executing following cases instructions.
# default:
# something else here ..
# break;
}
To me Exceptions are meant to raise errors and not really to control execution flaw.
If the break behaviour you are trying to set is not about unexpected error(s), Exception handling is not the right solution here :/.
$a = 1;
switch($a) {
case "1":
if ($condition1){
break;
}
if ($condition2){
break;
}
if ($condition3){
break;
}
}
In this way I got what I want. I use a switch only has a definite case and then use break in case to choose if condition. The reason why I use the break : condition1 and condition2 may both satisfy, in that situation only condition1 is applied .IF is selective according the order.
I had the same problem. A solution is to pile if.
The first example is simplistic but...
$a="test";
if("test"==$a)
{
do something
//break; We remove from your example
if(comparison) {
echo "yes";
}
}
echo "finish";
Or, you can use goto.
$a="test";
if("test"==$a)
{
do something
goto the_end_of_your_func;
echo "yes";
}
the_end_of_your_func:
echo "finish";
No.
But how about:
$a="test";
if("test"==$a)
{
if ($someOtherCondition)
{
echo "yes";
}
}
echo "finish";
Just move the code that is not supposed to be executed to else/elseif branch. I don't really see why would you want to do what you're trying to do.
The simple answer is that no, there isn't a way to break from an if statement without completely stopping the execution (via exit). Other solutions won't work for me because I can't change the structure of the if statement, since I'm injecting code into a plugin, like so:
if ( condition ) {
// Code and variables I want to use
// Code I have control over
// Code I don't want to run
}
// More code I want to use
Answering to your question whether that is achievable or not, then yes that is achievable using "goto" operator of php.
But ethically, its not a good practice to use "goto" and of there is any need to use goto then this means that code need to be reconstructed such that requirement of goto can be removed.
According to the sample code you posted above, it can be clearly seen that the code can be reconstructed and the code that is no more required can be either deleted or commented (if possibility is there for use in future).
$arr=array('test','go for it');
$a='test';
foreach($arr as $val){
$output = 'test';
if($val === $a) $output = "";
echo $output;
}
echo "finish";
combining your statements, i think this would give you your wished result.
clean and simple, without having too much statements.
for the ugly and good looking code, my recomandation would be:
function myfunction(){
if( !process_x() || !process_y() || !process_z()) {
clean_all_processes();
return;
}
/*do all the stuff you need to do*/
}
somewhere in your normal code
myfunction();
i have a simple solution without lot of changes.
the initial statement is
I want to break the if statement above and stop executing echo "yes"; or such code which is no longer necessary to be executed, there may be or may not be an additional condition, is there way to do this?
So it seems simple. try code like this:
$a="test";
if("test"==$a)
{
if (1==0){
echo "yes"; // this line while never be executed.
// and can be reexecuted simply by changing if (1==0) to if (1==1)
}
}
echo "finish";
if you want to try without this code, it's simple. and you can back when you want. another solution is comment blocks.
or simply thinking and try in another separated code and copy paste only the result in your final code.
and if a code is no longer nescessary, in your case, the result can be
$a="test";
echo "finish";
with this code, the original statement is completely respected
and more readable!
The simple solution is to comment it out.
$a="test";
if("test"==$a)
{
//echo "yes"; //no longer needed - 7/7/2014 - updateded bla bla to do foo
}
The added benefit is your not changing your original code and you can date it, initial it and put a reason why.
What about using ternary operator?
<?php
// Example usage for: Ternary Operator
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
?>
Which is identical to this if/else statement:
<?php
if (empty($_POST['action'])) {
$action = 'default';
} else {
$action = $_POST['action'];
}
?>
To completely stop the rest of the script from running you can just do
exit; //In place of break. The rest of the code will not execute
I'm late to the party but I wanted to contribute. I'm surprised that nobody suggested exit(). It's good for testing. I use it all the time and works like charm.
$a ='';
$b ='';
if($a == $b){
echo 'Clark Kent is Superman';
exit();
echo 'Clark Kent was never Superman';
}
The code will stop at exit() and everything after will not run.
Result
Clark Kent is Superman
It works with foreach() and while() as well. It works anywhere you place it really.
foreach($arr as $val)
{
exit();
echo "test";
}
echo "finish";
Result
nothing gets printed here.
Use it with a forloop()
for ($x = 2; $x < 12; $x++) {
echo "Gru has $x minions <br>";
if($x == 4){
exit();
}
}
Result
Gru has 2 minions
Gru has 3 minions
Gru has 4 minions
In a normal case scenario
$a ='Make hot chocolate great again!';
echo $a;
exit();
$b = 'I eat chocolate and make Charlie at the Factory pay for it.';
Result
Make hot chocolate great again!
$a="test";
if("test"!=$a)
{
echo "yes";
}
else
{
echo "finish";
}
if (isset($_GET['ssl'])) {
switch ($_GET['ssl']) {
case 1:
{
header("Location: https://site.com");
exit;
}
default:
{
header("Location: http://site.com");
exit;
}
}
}
Should I be using exit; because I'm using header? Or should I use break like the switch requires?
As I still feel bad about that whole exchange yesterday, I figured I'd offer an answer and explain some things to do with break and exit().
As amosrivera points out, using a break is not required within a switch statement; it is also valid within other loop structures.
From the manual:
break ends execution of the current
for, foreach, while, do-while or
switch structure.
What this means is that for each one of these loop types, it will stop execution of the current loop, but not the execution of the calling script itself. Note also:
break accepts an optional numeric
argument which tells it how many
nested enclosing structures are to be
broken out of.
The purpose is to stop executing the loop; in a switch, it prevents fall-through. For example:
function mySwitch($var) {
$return = '';
switch ($var) {
case 1:
$return .= 'a';
case 2:
$return .= 'b';
break;
case 3:
$return .= 'c';
}
return $return;
}
echo mySwitch(1); // outputs 'ab'
echo mySwitch(2); // outputs 'b'
echo mySwitch(3); // outputs 'c'
See live example: http://codepad.org/8EMvYt7V
switch will match the first case then run each case following until it reaches a break or return.
Concerning return, if called in a function within a loop, it will end the function execution and, possibly confusingly, return() will also end the current script execution if called in the global scope, but in a different way from exit() (for instance, for include'd or require'd files, it will not affect the main script).
How exit() (or die()) differ from break and return is that is ends execution of the entire script, not just the current loop (break), function (return), or script (return()).
Now, I happen to agree with coreyward that it's probable you don't need a switch for this; I use a different method under a potentially different scenario:
if (strtolower($_SERVER['HTTPS']) != 'on') {
exit(header("location: https://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}"));
}
Which could be rewritten to be:
if (strtolower($_SERVER['HTTPS']) != 'on' && $_GET['ssl']) {
exit(header("location: https://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}"));
}
Or you could create a lookup list of actions/pages that require ssl and call that in the redirect:
function requireSSL($page) {
$req = array('login.php','myaccount.php','updateaccount.php');
return in_array($page, $req);
}
function doSSLRedirect($page) {
if (strtolower($_SERVER['HTTPS']) != 'on' && requireSSL($page)) {
exit(header("location: https://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}"));
}
}
Then you can call this when you need to enforce a redirect (and you don't need $_GET['ssl'] in the URL):
doSSLRedirect($_SERVER['SCRIPT_NAME']);
This would be more handy if you're using some kind of MVC pattern and were checking for actions in the URL; otherwise, you could just use an include checkssl.php at the head of your script.
Since I don't know how you're actually implementing your SSL check, these are just suggestions. Looking at the code you have above, if that were simply plugged in at the top of a page, you might end up with an infinite loop if you inadvertently add the ssl variable back to the redirected URL.
As far as calling exit() (or die()), you don't have to pair the two, but they typically do occur at the same time or near each other, since any output that follows should not be seen by the user's browser.
For instance, if you separated them, you might create a check for the redirect in case you have other things you want to happen before exit (maybe some logging or something).
For example:
$sslredirected = false;
if (isset($_GET['ssl'])) {
switch ($_GET['ssl']) {
case 1:
header("Location: https://site.com");
$sslredirected = true;
default:
header("Location: http://site.com");
$sslredirected = false;
}
}
if ($sslredirected === true) {
$otherstuff = youNeedToDoBeforeRedirection();
exit;
}
However, in this case you could probably just as easily put that in an include'd file and just call that in your switch and let it do the exit() call. There's a number of different ways this could go.
One other note about using header(), you need to call it before anything is outputted (including whitespace). See http://codepad.org/nJ4aght4 for an example of what I mean. Note in this case, the header is not sent, so the redirect will not occur.
Hopefully this helps. :)
I think you mean switch requires break, and the point is, it doesn't requires it, break should be used when needed to after a condition, in this case you are already doing that with exit the way you have it is fine.
the whole code block is pointless in my opinion, you can achieve the exact same results like so:
$protocol = empty($_GET['ssl']) ? 'http' : 'https';
header("Location: " . $protocol . "://site.com");
exit;
the function empty will be true if the value the index is not defined as well as being empty or 0.
Use exit at the end if u need :
if (isset($_GET['ssl'])) {
switch ($_GET['ssl']) {
case 1:
{
header("Location: https://site.com");
break;
}
default:
{
header("Location: http://site.com");
}
}
}
exit;
switch isn't really appropriate here — it's making things more complicated, not less.
if (isset($_GET['ssl']) {
header('Location: ' . ($_GET['ssl'] ? 'https' : 'http') . '://example.com/');
exit();
}