PHP exit only current included script file from inside a function - php

I know I can use return to exit current script file, but what if we want to exit current script from inside a function?
For example, we define a exitScript() function that prints closing html tags and exits current script file, but if we use return it only exits from current function. Also exit() terminates whole script not only current file.

You can use Exceptions to do this, not particularly elegant, but this should do what your after, replace these methods.
public function fn1()
{
try {
$fn2 = $this->fn2();
}
catch ( Exception $e ) {
}
echo 'I want this to be displayed no matter what!';
}
public function fn4()
{
$random = rand(1, 100);
if ($random > 50)
{
return true;
}
else
{
// I want to exit/break the scirpt to continue running after
// the $fn2 = $this->fn2() call in the $this->fn1() function.
//exit();
throw new Exception();
echo "This shouldn't be displayed.";
}
}

You can return from an included file to the 'main file', skipping execution of the remaing part after the return.
So this will output: ABXend, skipping C
a.php
<?php
echo 'A';
include('b.php');
echo 'end';
?>
and b.php
<?php
echo 'B';
if(!x(6))return; //return here
echo 'C';
function x($num){
echo 'X';
if($num!==1)return false;
}
?>

Related

Check if method is false then output results

I have a class that contains a method which carries out various database checks. It then returns the value, if exists.
Here is a very basic setup example:
PHP Class
class myClass{
var $aVar1;
var $aVar2;
function myMethod()
{
// database query
// if results from query return **results**
// else return false
}
}
HTML/PHP File
// setup $myClass object var
<?php if($myClass->myMethod(): ?>
// lots of html
<?php echo $myClass->myMethod() ?>
// lots of html
<?php endif; ?>
This occurance happens multiple times throughout my file with different methods. My question is, I am calling the method initially and checking if it's false and then calling it again to echo the output.
I could do the following but would end up with a variable declaration on every method. There must be a more professional approach?
<?php
$myMethod = $myClass->myMethod();
if($myMethod): ?>
// lots of html
<?php echo $myMethod ?>
// lots of html
<?php endif; ?>
Is there a cleaner more efficient way of doing this?
Age old problem. One common technique is to store the return val in a temporary variable
$result=$myClass->myMethod();
if($result!=FALSE)
echo $result;
You can also use a simpler version
if($result=$myClass->myMethod())
echo $result;
And you can also use the simplest one!
echo $myClass->myMethod() ?: '';
Simpler than the simplest one!
echo $result=$myClass->myMethod();
You can do this to reduce verbosity:
<?php
function foo($bool = true) {
$result = array();
if($bool) {
$result = array('bar');
}
return $result;
}
if(! array()) {
echo 'empty array evaluates to false.';
}
if($result = foo()) {
var_export($result); // Will dump array with 'bar'.
}
if($result = foo(false)) {
var_export($result); // Won't happen.
}
If your return is truish then the contents of the if will execute.

Problems with using include command in PHP

I have a PHP script that executes another PHP script(that contains quite a lot of functions some being recursive) using the include method , multiple times, but the second time i get a error saying that one of the function in the "included" PHP script can not be redeclared.
Now i get that what include does is just inserting the commands from the referenced script in the script that called it and thus I have like the same functions declare too many times resulting in a abomination.
So, could somebody tell me how i should approach this problem?
This is the included script
<?php
$_SESSION['det']=0;
$x=array();
function valid($k)
{
for($i=1;$i<$k;$i++)
if($GLOBALS['x'][$i]==$GLOBALS['x'][$k])
return 0;
return 1;
}
function semn($k)
{
$nr=0;
for($i=1;$i<$k;$i++)
for($j=$i+1;$j<=$k;$j++)
if($GLOBALS['x'][$i]>$GLOBALS['x'][$j])
$nr++;
if($nr%2==0)
return 1;
else
return -1;
}
function determinant($k)
{
$prod=1;
for($i=0;$i<$k;$i++)
$prod*=$_SESSION['matrix'][$i][$GLOBALS['x'][$i+1]-1];
$_SESSION['det']+=semn($k)*$prod;
}
function solve($k,$n)
{
for($i=1;$i<=$n;$i++)
{
$GLOBALS['x'][$k]=$i;
if(valid($k))
if($k==$n)
{
determinant($k);
}
else
solve($k+1,$n);
}
}
$n=$_SESSION['size'];
solve(1,$n);
unset($x);
?>
And this is the script thats includes.
<?php
include 'determinant.php';
if(!$_SESSION['det'])
{
echo "The inverse cant be calculated cause the determinant is equla to 0.";
}
else
{
$detA=$_SESSION['det'];
//Transpusa
for($i=0;$i<$_SESSION['size']-1;$i++)
for($j=$i+1;$j<$_SESSION['size'];$j++)
{
$aux=$_SESSION['matrix'][$i][$j];
$_SESSION['matrix'][$i][$j]=$_SESSION['matrix'][$j][$i];
$_SESSION['matrix'][$j][$i]=$aux;
}
$Dcar=array();
//Matricile caracteristice
for($i=0;$i<$_SESSION['size'];$i++)
{
for($j=0;$j<$_SESSION['size'];$j++)
{
$r=0;
$c=0;
$semn=1;
$a=array();
$_SESSION['matrix'][$i][$j]
for($m=0;$m<$_SESSION['size'];$m++)
{
if($m==$i)
continue;
else
{
for($n=0;$n<$_SESSION['size'];$n++)
{
if($n==$j)
continue;
else
{
$a[$r][$c]=$_SESSION['matrix'][$m][$n];
$c++;
}
}
$r++;
$c=0;
}
}
//Apelarea functiei determinant pentru fiecare matrice
$aux=$_SESSION['matrix'];
$_SESSION['matrix']=$a;
$_SESSION['size']-=1;
include 'determinant.php';
$_SESSION['matrix']=$aux;
$_SESSION['size']+=1;
$Dcar[$i][$j]=($semn*$_SESSION['det'])/$detA;
$semn*=-1;
}
}
for($i=0;$i<$_SESSION['size'];$i++)
{
for($j=0;$j<$_SESSION['size'];$j++)
echo $Dcar[$i][$j]." ";
echo "<br>";
}
}
?>
Use include_once() function.
Follow documentation:
This is a behavior similar to the include statement, with the only
difference being that if the code from a file has already been
included, it will not be included again. As the name suggests, it will
be included just once.
You can use require_once() instead. It's all in the name in this case ;-)

Calling function in another function

I have a function printContent() which prints the arguments and logged() which checks if the user is logged in.
My point is to do something like this:
logged("printContent('TITLE', 'CONTENT', 1)", 1);
It doesn't work. It should printContent() if user is not logged in, but nothing is happening. If I'll try changing return() into print() it prints the text "printContent(text...)".
Here are these two functions:
function logged($echo = 0, $logout = 0)
{
if($_SESSION['user'])
{
if($echo)
{
if(!($logout)) return $echo;
else return false;
}
else return true;
}
else
{
if($logout == 1) return $echo;
else return false;
}
}
function printContent($title, $content, $type = 0){
if($type == 1){
echo '<div class="right-box">';
if($title) echo '<h3>'.$title.'</h3>';
echo $content.'</div>';
}
else {
echo '<div class="left-box">';
if($title) echo '<h2>'.$title.'</h2>';
echo '<div class="left-box-content">'.$content.'</div></div>';
}
}
It should printContent() if user is not logged in
You can try
if(!logged())
{
printContent('TITLE', 'CONTENT', 1);
}
Your logged() function is too complicated; the $echo and $logout parameters make the logic extremely hard to follow. You should simplify it to just this, doing one thing very well:
function isLoggedIn()
{
return !empty($_SESSION['user']);
}
Then, the logic becomes quite simple afterwards:
if (!isLoggedIn()) {
printContent('title', 'content', 1);
}
Play time
Being fancy, you could do this since 5.3, though it's a very contrived example of what you could accomplish with anonymous functions:
function ifLoggedIn($loggedIn, $loggedOut)
{
return empty($_SESSION['user']) ? $loggedIn() : $loggedOut();
}
The $loggedIn and $loggedOut parameters are the callback parameters and get executed from inside the function, based on whether the user is logged in or not. To use it:
ifLoggedIn(function() {
}, function() {
printContent('TITLE', 'CONTENT', 1);
});
What you seem to be looking for is a callback.
If I understand you correctly, you wish printContent only to execute, if the user is logged in, correct?
You may want to check this question for further info: How do I implement a callback in PHP?
you are trying to execute a plain string. Use
function1( function2() );
that is the same as
$tmp = function2();
function1($tmp);

Is exit needed after return inside a php function?

<?php
function testEnd($x) {
if ( ctype_digit($x) ) {
if ( $x == 24 ) {
return true;
exit;
} else {
return false;
exit;
}
} else {
echo 'If its not a digit, you\'ll see me.';
return false;
exit;
}
}
$a = '2';
if ( testEnd($a) ) {
echo 'This is a digit';
} else {
echo 'No digit found';
}
?>
Is exit needed along with return when using them inside a php function? In this case, if anything evaluated to false, i'd like to end there and exit.
No it's not needed. When you return from a function then any code after that does not execute. if at all it did execute, your could would then stop dead there and not go back to calling function either. That exit should go
According to PHP Manual
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 will also end the execution of
an eval() statement or script file.
Whereas, exit, according to PHP Manual
Terminates execution of the script.
So if your exit was really executing, it would stop all the execution right there
EDIT
Just put up a small example to demonstrate what exit does. Let's say you have a function and you want to simply display its return value. Then try this
<?php
function test($i)
{
if($i==5)
{
return "Five";
}
else
{
exit;
}
}
echo "Start<br>";
echo "test(5) response:";
echo test(5);
echo "<br>test(4) response:";
echo test(4);
/*No Code below this line will execute now. You wont see the following `End` message. If you comment this line then you will see end message as well. That is because of the use of exit*/
echo "<br>End<br>";
?>

how to use PHP magic constants from other classes?

i have created below function in a file info.php to debug variable & data during page load
class Info {
static function watch($what,$msg='',$more=FALSE)
{
echo "<hr/>";
echo "<br/>".$msg.":";
if( is_array($what) || is_object($what) )
{
echo "<pre>";
print_r($what);
echo "</pre>";
}
else{
echo $what;
}
if($more)
{
echo "<br/>METHOD:".__METHOD__;
echo "<br/>LINE:".__LINE__;
}
}
}
now i call this method from another page index.php, where i inculded info.php
in this file i want to debug POST array, so i write below code
class Testpost {
__construct() { // some basic intializtion }
function getPostdata($postarray) {
$postarray=$_POST;
Info::watch($postarray,'POST ARRAY', TRUE);
}
everything is working fine but method and LINE appears below
METHOD:Info::watch();
LINE:17 // ( where this code is written in Info class)
but i wantbelow to display
METHOD: Testpost::gtPostdata()
LINE:5( where this function is called in Testpost class)
so how do i do that if i put$more=TRUE in watch() then method and line number should be diaply from the class where it is called.
can i use self:: or parent::in watch method?? or something else
please suggest me how to call magic constants from other classes or is there any other method to debug varaibale?? ( please dont suggest to use Xdebug or any other tools)
You have to use the debug_backtrace() php function.
You also have below the solution to your problem. Enjoy! :)
<?php
class Info {
static function watch($what,$msg='',$more=FALSE)
{
echo "<hr/>";
echo "<br/>".$msg.":";
if( is_array($what) || is_object($what) )
{
echo "<pre>";
print_r($what);
echo "</pre>";
}
else{
echo $what;
}
if($more)
{
$backtrace = debug_backtrace();
if (isset($backtrace[1]))
{
echo "<br/>METHOD:".$backtrace[1]['function'];
echo "<br/>LINE:".$backtrace[1]['line'];
}
}
}
}
You can not use those constants from that scope. Check out the function debug_backtrace() instead. If it gives you too much info, try to parse it.
debug_bactrace is the only way you could totally automate this, but it's a "heavy-duty" function.... very slow to execute, and needs parsing to extract the required information. It might seem cumbersome, but a far better solution is to pass the necessary information to your Info::watch method:
class Info {
static function watch($whereClass,$whereLine,$what,$msg='',$more=FALSE)
{
echo "<hr/>";
echo "<br/>".$msg.":";
if( is_array($what) || is_object($what) )
{
echo "<pre>";
print_r($what);
echo "</pre>";
}
else{
echo $what;
}
if($more)
{
echo "<br/>METHOD:".$whereClass;
echo "<br/>LINE:".$whereLine;
}
}
}
now i call this method from another page index.php, where i inculded info.php
class Testpost {
__construct() { // some basic intializtion }
function getPostdata($postarray) {
$postarray=$_POST;
Info::watch(__METHOD__,__LINE__,$postarray,'POST ARRAY', TRUE);
}

Categories