use goto inside function php - php

Is there a way to define global label (something like variables) for PHP goto, in order to use it inside function declaration. I want to do the following:
function myFunction() {
if (condition) {
goto someLine;
}
}
someLine:
// ....
myFunction();
when I use this code it says
PHP Fatal error: 'goto' to undefined label "someLine"
I know that it is not recommended to use goto statement. But I need it in my case. I know that perhaps always there are alternatives of goto, just in my case it would make the code a little easier and understandable

You cannot goto outside of a function I believe: http://php.net/manual/en/control-structures.goto.php
Direct Quote:
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.
This might have to do with the fact that php is parsed and jumping out of a function will cause a memory leak or something because it was never properly closed.
Also as everyone else said above, really you don't need a goto. You can just return different values from the function and have a condition for each. Goto is just super bad practice for modern coding (acceptable if you are using basic).
Example:
function foo(a) {
if (a==1) {
return 1;
} elseif (a==3) {
return 2;
} else {
return 3;
}
}
switch (foo(4)) { //easily replaceable with elseif chain
case 1: echo 'Foo was 1'; break; //These can be functions to other parts of the code
case 2: echo 'Foo was 3'; break;
case 3: echo 'Foo was not 1 or 3';
}

There's no way to jump in or out of a function. But since you state that you need it, here's an alternative route.
function myFunction() {
if (condition) {
return true;
}
return false;
}
someLine:
// ....
$func = myFunction();
if($func == true) goto someLine;

As previously stated you can't. As for "I need it", I highly doubt this. Whatever code you have at someLine: can easily be made into a function that you can call from the other if needed.

yeah there's a way as long as that function is declared on the same php file or is included if its on another script,
the best way to jump on to someline is to return that goto code of yours dude so that if function is called a return value is received.. hope this helps
function foo($b="30")
{
$a=30;
if($a==intval($b))
return "someline:goto
someline";
}
try{
eval(foo());
}
catch(IOException $err)
{
exit($err);
}
/*someline is somewhere here
for example */

Related

Force return statement on caller function

I am just curious if it's possible to force parent method to return a value from within method called in that parent method? Let's say I have:
public function myApiEndpoint()
{
// I DO NOT want to to have return statement here
$this->validOrUnprocessable();
// some other code
//return value
return $someValue;
}
public function validOrUnprocessable()
{
if ($condition) {
... here goes the code that forces return statement on myApiEndpoint function without putting the word `return` in front of this call...
}
}
So in other words validOrUnprocessable method, when it needs to do so forces or tricks PHP into thinking that myApiEndpoint returns the value. I do not want to use return statement when validOrUnprocessable is called or any if conditions.
I do know other ways of doing what I want to do but I wanted to know if something like that is possible. I am not interested in any workarounds as I know very well how to implement what I need to achieve in many other ways. I just need to know if this what I described is possible to do exactly how I described it.
I did try to get there with reflections and other scope related things but so far no luck. Any ideas?
Just to add. I am doing this because I want to check how far I can push it. I am building a tool for myself and I want it to be as convenient and easy to use as possible.
If it's not possible I have another idea but that's a bit out of the scope of this post.
You should throw an exception.
public function validOrUnprocessable()
{
if ($condition) {
throw Exception('foo bar');
}
}
The code calling this method should be ready to catch an exception:
public function myApiEndpoint()
{
try {
// I DO NOT want to to have return statement here
$this->validOrUnprocessable();
// some other code
//this code will never be called because of exception thrown in validOrUnprocessable
return value;
} catch (Exception $e) {
//do something else
return -1; //you can return another value as example.
}
return $someValue;
}

php variable not detected

im having trouble with my php program, it seems that my array variable being declared earlier wasn't detected in a function. Here's my code :
$msg = array(
//Errors List
'Error1' => 'Error 1',
'Error2' => 'Error 2'
);
//Class for outputting Messages
class Message {
static function Info($string) { echo $string; }
static function Error($string) { echo $string; }
}
//Functions
function function1($var1) {
if (!preg_match("/^[0-9]+$/", $var1)){
Message::Error($msg['Error1']);
}
when i run it, and example i test the program like this..
$test = 'blabla';
function1($test);
it says the msg variable was undefined. Can anyone tell me how to resolve this?
Thanks in advance.
There are three ways to solve this issue.
Passing the required global var as a parameter
In my opinion, this is the preferred solution, as it avoids the pollution of your function with global variables. Global variables tend to introduce unexpected side effects and make maintenance and reuse of code a lot harder. A very extensive article on why you should avoid globals whenever possible (and some alternative solutions) can be found in the c2 wiki
function function1($var1,$mesg) {
if (!preg_match("/^[0-9]+$/", $var1)){
Message::Error($mesg['Error1']);
}
}
The call to function1 changes to
function1($test,$msg);
Using global:
Same effect as the one just below, other notation.
function function1($var1) {
global $msg;
if (!preg_match("/^[0-9]+$/", $var1)){
Message::Error($msg['Error1']);
}
}
Using the $GLOBALS superglobal
Some sources say this form is slightly faster than the one using global
function function1($var1) {
if (!preg_match("/^[0-9]+$/", $var1)){
Message::Error($GLOBALS['msg']['Error1']);
}
}
you can not use $msg as a local variable in function.
function function1($var1) {
global $msg;
if (!preg_match("/^[0-9]+$/", $var1)){
Message::Error($msg['Error1']);
}
}

what will happen if we have more statements in coding after function return code?

I have basic question for you guys
i have php function which verifies and creates the file handler name for the given type,
however i just want to know if the following code goes to a else, will the next lines of the coding of creating the guid will be executed or will it be ignored ?
private function fileFormat($type=false){
if($type=='CreditCard')
$prefix='CC-';
elseif($type=='DirectDebit')
$prefix='DD-';
else
return false;
$date = $prefix.'-'.date('d-m-Y', time());
$guid = '' . md5($date) . '.csv';
return $guid;
}
They will be ignored. Anything after return statement will not be executed.
Whenever the return false is executed the following lines will not be executed. However you must make sure at the spot you call your function you can 100% distinguish between the return values from return false and a return $guid
No more lines execute after a return statement is executed.
Simply it will not execute (ignore) the lines following return.
Not to beat a dead horse, now that there are a number of answers stating the same thing... but here is my clarification.
After a return is executed, no remaining code will be executed. The way you have setup your code is fine, assuming you want a false returned if neither of the $types are encountered. This is a common control flow and is preferred over setting a flag and checking the flaw before return.
if ($myCondition_1) {
$a = 1;
} elseif ($myCondition_2) {
$a = 2;
} else {
return False;
}
other_operation_on_a($a);
return $a;
Is preferred (for me) over:
$a = False;
if ($myCondition_1) {
$a = 1;
} elseif ($myCondition_2) {
$a = 2;
}
if ($a !== False) {
other_operation_on_a($a);
}
return $a;
The function will return and everything after the encountered return statement will not be executed.
They'll be ignored because the return will be executed by the else (default) case.
The idea is that control is returned to the calling method.... So those lines will never execute.
For example if your IDE is good, you are given warnings in the case of redundant statements after the return e.g:
function PrintHelloWorld()
{
if($userPresent)
{
echo "Hello World" ;
}
return "World empty!";
$something = "blah" ; //redundant (will never execute)
$something+="Blah" ; //redundant (will never execute)
//A good IDE should give warnings. But you usually see them as grayed out
}

Start function over, depending on results of IF statement

If I have a function that is inside of a Class, and I am returned with "invalid" how can I start back up at the top function?
function test(){
//curl here
//other stuff here
if(strpos($data, 'invalid')){
print "invalid";
//discard and remove
continue ;
}
}
but I get the following error
Fatal error: Cannot break/continue 1 level in
If I am hit with "invalid" I would like to start test() back over..
You probably want to use a recursive function here:
function test(){
//curl here
//other stuff here
if(strpos($data, 'invalid')){
print "invalid";
//discard and remove
return test() ; // restart process
}
}
Alternatively, this may be a (very rare) good use of the goto operator:
function test(){
start:
//curl here
//other stuff here
if(strpos($data, 'invalid')){
print "invalid";
//discard and remove
goto start;
}
}
Note that this will only work in PHP >=5.3.
I'd make use of exceptions, and let the calling scope control repeat invocations of test(). test() performs one job; it shouldn't control when it's asked to perform that job.
(Recursive approaches given in other examples don't really fit the use case [and make me nervous, thanks to languages where recursing too many times makes you run out of stack space eventually; certainly you're filling up your stack for no reason], and though goto will work fine it still gives the function itself too much power.)
function test()
{
//curl here
//other stuff here
if (strpos($data, 'invalid'))
throw new Exception("Data is invalid");
}
function callingFunction()
{
while (true) {
try {
test();
break; // only reached if test() didn't throw
}
catch(Exception $e) {} // if we fall into this, the loop repeats
}
}
You could still apply goto quite cleanly with this approach:
function test()
{
//curl here
//other stuff here
if (strpos($data, 'invalid'))
throw new Exception("Data is invalid");
}
function callingFunction()
{
startTest:
try {
test();
}
catch(Exception $e) {
goto startTest;
}
}
Remove continue; and instead add test();. It's called recursive functions (calling itself).
There are a few ways you can do it, the way my teacher normally suggests is to actually call the function again.
function test(){
//curl here
//other stuff here
if(strpos($data, 'invalid')){
print "invalid";
//discard and remove continue ;
test();
return;
}
}
My answer might not be the best, hope this helps.
Assuming you change the parameters beforehand, you can recursively call the function again with new parameters. Just make sure there will be an edge case where the function will stop recursing. As for that, I'd need to see the real code to tell you.
function test($data){
//curl here
//other stuff here
if(strpos($data, 'invalid')){
print "invalid";
//discard and remove
test($NEW_DATA);
}
}
If you want to break out of the function you're currently in, you should use 'return' instead of 'continue'.
Or if you would like to start the processing over, you should put your logic into a loop.

Is it possible to make an object return false by default?

I tried to ask this before, and messed up the question, so I'll try again. Is it possible to make an object return false by default when put in an if statement? What I want:
$dog = new DogObject();
if($dog)
{
return "This is bad;"
}
else
{
return "Excellent! $dog was false!"
}
Is there a way this is possible? It's not completely necessary, but would save me some lines of code. thanks!
No, PHP has no support for operator overloading. Maybe they'll add it in a future version.
Use the instanceof keyword.
For example
$result = Users->insertNewUser();
if($result instanceof MyErrorClass){
(CHECK WHAT WENT WRONG AND SAY WHY)
} else {
//Go on about our business because everything worked.
}
Info is here.
Use this? Not a real neat solution, but does what you want:
<?php
class Foo
{
private $valid = false;
public function Bar ( )
{
// Do stuff
}
public function __toString ( )
{
return ( $this -> valid ) ? '1' : '0';
}
}
?>
Zero is considered false, one is considered true by PHP
I was attempting to do this myself and found a solution that appears to work.
In response to the others who were trying to answer the question by telling the asker to use a different solution, I will also try to explain the reason for the question. Neither the original poster or I want to use an exception, because the point is not to use exception handling features and put that burden on any code we use this class in. The point, at least for me, was to be able to use this class seamlessly in other PHP code that may be written in a non-object-oriented or non-exception-based style. Many built-in PHP functions are written in such a way that a result of false for unsuccessful processes is desirable. At the same time, we might want to be able to handle this object in a special way in our own code.
For example, we might want to do something like:
if ( !($goodObject = ObjectFactory::getObject($objectType)) ) {
// if $objectType was not something ObjectFactory could handle, it
// might return a Special Case object such as FalseObject below
// (see Patterns of Enterprise Application Architecture)
// in order to indicate something went wrong.
// (Because it is easy to do it this way.)
//
// FalseObject could have methods for displaying error information.
}
Here's a very simple implementation.
class FalseObject {
public function __toString() {
// return an empty string that in PHP evaluates to false
return '';
}
}
$false = new FalseObject();
if ( $false ) {
print $false . ' is false.';
} else {
print $false . ' is true.';
}
print '<br />';
if ( !$false ) {
print $false . ' is really true.';
} else {
print $false . ' is really false.';
}
// I am printing $false just to make sure nothing unexpected is happening.
The output is:
is false.
is really false.
I've tested this and it works even if you have some declared variables inside the class, such as:
class FalseObject {
const flag = true;
public $message = 'a message';
public function __toString() {
return '';
}
}
A slightly more interesting implementation might be:
class FalseException extends Exception {
final public function __toString() {
return '';
}
}
class CustomException extends FalseException { }
$false = new CustomException('Something went wrong.');
Using the same test code as before, $false evaluates to false.
I recently had to do something similar, using the null object pattern. Unfortunately, the null object was returning true and the variable in question was sometimes an actual null value (from the function's default parameter). The best way I came up with was if((string)$var) { although this wouldn't work for empty arrays.
Putting something in "an if statement" is simply evaluating the variable there as a boolean.
In your example, $dog would need to be always false for that to work. There is no way to tell when your variable is about to be evaluated in a boolean expression.
What is your ultimate purpose here? What lines of code are you trying to save?
I'm not sure about the object itself. Possible. You could try something like, add a public property to the DogObject class and then have that set by default to false. Such as.
class DogObject
{
var $isValid = false;
public function IsValid()
{
return $isValid;
}
}
And then when you would instantiate it, it would be false by default.
$dog = new DogObject();
if($dog->IsValid())
{
return "This is bad;"
}
else
{
return "Excellent! $dog was false!"
}
Just a thought.
If I understand what your asking, I think you want to do this:
if (!$dog){
return "$dog was false";
}
The ! means not. SO you could read that, "If not dog, or if dog is NOT true"
Under what conditions do you want if($dog) to evaluate to false? You can't do what you've literally asked for, but perhaps the conditioned could be replaced by something that does what you want.
class UserController
{
public function newuserAction()
{
$userModel = new UserModel();
if ($userModel->insertUser()) {
// Success!
} else {
die($userModel->getError());
}
}
}
Or
class UserController
{
public function newuserAction()
{
$userModel = new UserModel();
try {
$userModel->insertUser()
}
catch (Exception $e) {
die($e);
}
}
}
There are a million ways to handle errors. It all depends on the complexity of the error and the amount of recovery options.
How about using an Implicit Cast Operator like the following C# ?
like so:
class DogObject
{
public static implicit operator bool(DogObject a)
{
return false;
}
}
Then you can go...
var dog = new DogObject();
if(!dog)
{
Console.WriteLine("dog was false");
}

Categories