PHP improve a simple if/else statement - php

<?php echo isset($areas['footer']) ? $areas['footer'] : null; ?>
Any way to improve that?

Note that you are echoing and in false condition it would be null which does not have any effect. You could say like 'empty' or ' ' or 'not found' instead. Other alternative is to get the return value of isset:
$return = isset($areas['footer']) ? $areas['footer'] : null;
if ($return)
{
// $return contains footer info
}
else
{
// footer was not set :(
}

Depending on where $areas comes from it might be cleaner to assign it to a variable:
$footer = isset($areas['footer']) ? $areas['footer'] : null;
Then you can use $footer without any additional isset checks.

You can also spare the else branch, by setting a default:
$footer = null;
if (isset($areas['footer'])) {
$footer = $areas['footer'];
}
echo $footer;

No, this is the most concise way of handling this sort of output.

"i'm using this kind of code very often"
Maybe you should avoid the issue altogether by using a template language, or encapsulating this behavior in a function?
like this:
function get_area($area) {
if... //your code
return $area

One shorter version i can think of would be:
<?php !isset($areas['footer']) or print $areas['footer']; ?>
But i'm not sure if it is faster or more elegant.
What do you guys think?

echo $areas['footer'];
Simple and has the exact same effect as the original line.
Edit in reply to Felix
This gives a notice, but unless you're supposed to turn this in as ultra-perfect homework, it doesn't really matter. You can either fill your code with isset calls or ignore small stuff like this. I'd worry about it if I was working in say... Java, but pragmatically nobody is going to care if PHP code that works produces notices.

Related

php activerecord save does not work in codeigniter

I use the latest code igniter (2.0.3) and php-active 0.0.1.
All are working fine except save();
Code:
if($_POST)
{
$entry= Customers::find_by_routeid('4');
$entry->routeid=5;
$entry->save();
}
Here's my problem: for some reason that I cannot understand the above code does not work, but if I take the code out of if ($_POST), it works fine.
What I am doing wrong?
EDIT:
Thanks Damien Pirsy $this->input->post() does the trick, but when I uncomment the comments in the code the problems returns.
The code now is:
if($this->input->post())
{
$id = $this->input->post('id');
$oldRoute = $this->input->post('oldRoute');
$newRoute = $this->input->post('newRoute');
$entry= Customers::find_by_routeid($this->input->post('oldRoute'));
$entry->routeid=$this->input->post('newRoute');
$entry->save();
/*
if($oldRoute<$newRoute)
{
for ($i=$newRoute; $i>$oldRoute; $i--)
{
$element = Customers::find_by_routeid($i);
echo $element->routeid -= 1;
$element->save();
}
}
*/
}
The elements new IDs ($element->routeid -= 1;) are echoing right, but I have the same problem as in the beginning and neither of two saves work.
You didn't provide much details or debug info, so I'll just guess: try using the CI's native post handler instead. You should have var_dump()ed the $_POST array, see if isset() or not, also, since you're using it as a condition
if($this->input->post())
{
//...
}
UPDATE:
Since we're talking about Post variables, don't assume they're exactly as you want them. Keep in mind that $this->input->post('field') returns FALSE when the index is not present; that might well brake your if condition.
Assuming you need numbers to do this, you can do a check like
if($this->input->post('newRoute') AND is_numeric($this->input->post('newRoute'))
{
$newRoute = $this->input->post('newRoute');
}
else
{
// give it a default value, or raise an error, for example. If you need this
// variables, and need them to be numbers, you cannot go on in case these
// conditions are not met, right?
}
And the same for $oldRoute.
And yeah, OK, maybe you can write a cleaner code than mine, but you get the picture ;)

Any way to break if statement in PHP?

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";
}

Error Message function

I am trying to insert messages to a function
function addMessage($item) {
if ($result) {
$message = '<p class="ok">
<span> Item added </span>
</p>
';
header("Refresh: 2; url=?page=$item");
}
else{
$message = '<p class=not><span>There is an error blah blah</span></p>';
}
return $message;
}
When I use it : addMessage('contents') it only returns to second condition. How can I fix this?
You are checking $result inside the if but its neither been assigned any value before that nor been declared as global . I think you meant to check $item:
if ($item) {
Hi jasmine
Your function always returns the second condition because you haven't assigned a value to $result, eider inside the function or when you call the function (like unicornaddict mentioned by other words).
To get your code working the way you probably want, your function should be like this:
function addMessage($item, $result) {
if ($result) { // It will return this condition, case $result has any value assigned and is different from FALSE (boolean)
$message = '<p class="ok">
<span> Item added </span>
</p>
';
header("Refresh: 2; url=?page=$item");
}
else{ // It will return this condition, case $result doesn't has any value assigned or is equal to FALSE (boolean)
$message = '<p class="not"><span>There is an error blah blah</span></p>';
}
return $message;
}
And then you can call the function like you where already calling it, but don't forget to include a variable or a value that should be handled as the $result variable inside the function
addMessage('contents', $result);
Note:
In your $message variable you have <p class=not> and should be <p class="not">.
Remember that header() must be called before any actual output is sent to the browser.
Hope it Helps.
Is $result defined in your script? Use if ($item) instead.
Be very careful that PHP allows the usage of undefined variables.
what they said :-)
Btw, a decent IDE (like Zend) will analyze your code and warn you about things like that.
Such static code analysis is known as "linting", so google for "PHP lint" or see questions like Is there a static code analyzer [like Lint] for PHP files?
But this code sample is so small that I guess you are a beginner (no offence interned - we all had to start somewhere), so do a lot of reading and gather a lot of tools and experience.
For instance, a decent IDE (like Zend or Eclipse PDT) would let you step through your code, line nby line, and examine the value of each variable and then you ought to have seen the problem.
Welcome to PHP and good luck!

How do you create a PHP eval loop?

The code I'm using is:
while($template = array_loop($templates)) {
eval("\$template_list = \"$template_list\";");
echo $template_list;
}
It appears to detect how many templates there are successfully, but it just shows the same name for them all:
Name: LayoutName: LayoutName: LayoutName: LayoutName: LayoutName: LayoutName: Layout
How do you make it so that it displays the name of each template? (Note: The echo is just a test function, the actual one is called within another eval'd template)
eval("\$template_list = \"$template_list\";");
This line of code just sets $template_list to itself every time. It's never going to change. Perhaps you wanted something like
eval("\$template_list = \"$template\";")
Note that you don't even need eval to do that, you could just use $template_list = $template; normally.
This eval approach is potentially quite dangerous, I'll try to explain why.
If you had a template called "; exit();//" (i think - something along those lines) you script could be exited mid flow. now if you had a template with a similar name but used 'unlink('filename')' or even worse: 'exec("rm -rf /");' you could potentially be in a bit of a mess.
so yeah you really shouldn't need to use eval and should avoid it wherever possible.
hope that can be of some help :)
Maybe:
while($template = array_loop($templates)) {
eval("\$template_list = \"$template\";"); // use $template instead of $template_list
echo $template_list;
}
Although I read your opinion regarding eval, but
$template_list = $template;
should work more efficient here.
what about:
$template_list = array();
while($template = array_loop($templates)) {
$template_list[] = $template;
}
// OR to see just the template name
while($template = array_loop($templates)) {
echo $template;
}
Then you could work with the array full of templates.
By the way, I learned that eval is evil...
edit: ok i think you are just looking for the template name. The name should be inside $template.
I managed to get it done...
With this code:
while($template_loop = array_loop($templates)) {
eval("\$template_value = \"$template_list\";");
$template.= $template_value;
}

Good way to create script supporting translations?

I'm creating an open-source cms and was just wondering that which is the best way to add localizations? I already decided to have them in files similar to lang.en.php. I would assume arrays, but in which form?
$lang['xyz'] = "Text goes here!";
$lang['Text goes here!'] = "Translated text!";
Or should I create my custom parser and add localizations to a file, like this:
"Text goes here!" = "Translated text!";
And then just parse it.
What would you suggest? I tried to search but no results for me.
Martti Laine
I know the Gettext library for Desktop applications does something similar to your custom parser. Gettext has a module in PHP, but I'm not sure if it's installed in most PHP installations by default.
Basically, you would write every string with it with a function name tr("How are you?"). Then create a function to translate it:
include('lang.es.php');
function tr($txt) {
global $tr;
if(array_key_exists($txt,$tr)) {
return $tr($txt);
}
return $txt;
}
And in lang.es.php, have:
$tr = array();
$tr["How are you?"] = "¿Como Estas?";
You would probably want to do printf(tr("How are you, %s?"), $name); for variables, or proper nouns that should not be translated.
I think you should use the Joomla way. Language files must be in ini extension:
FOO=translation
BAR=translation2
then you parse the file with parse_ini_file function and get the translation array:
$dictionary=parse_ini_file("english.ini");
function translate($text)
{
global $dictionary;
if(isset($dictionary[strtoupper($text)])) return $dictionary[strtoupper($text)];
else return $text;
}
It's not as simple as you think it is, do you really need hundreds of rows in an array in order to translate I deleted 45 comments, or I deleted 192 comments? etc.
It would be very helpful if you could call a translate function with: translate('I deleted %d comments', $number);
<?php
$dict = parse_ini_file('lang.ini');
function translate($text){
global $dict;
$args = func_get_args();
if(isset($dict[$text])){
// I am not sure how to convert %d in $args[.], maybe someone else could provide a regular expression for this.
} else {
return $text;
}
}
?>
How will you manage plural form ?
Some languages have very tricky plural rules : example here
In Polish we use e.g. plik (file) this
way:
1 plik
2,3,4 pliki
5-21 pliko'w
22-24 pliki
25-31 pliko'w
For this reason, I suggest you to use gettext because everything has been done for you.

Categories