Difference between JRequest::getVar($var) and $var in Joomla/PHP? - php

Let me start by saying I know nothing about Joomla or PHP so i might be comparing apples to oranges here but....
I keep seeing JRequest::getVar($var) and $var in some code i've been looking at. Can someone explain what the difference between these two is?
According to Joomlas' documentation getVar , "Fetches and returns a given variable." If that is the case why would the following code return different results?
echo JRequest::getVar($amount);
echo $amount;

Disclaimer: I don't know the first thing about Joomla.
Looking at the documentation, JRequest::getVar fetches values from GET or POST parameters and is supposed to be used like JRequest::getVar('amount') (note the argument is a string, not a variable). echo $amount and echo JRequest::getVar($amount) are of course nowhere near equivalent, the former means "echo the value of $amount", the latter "echo the value of a GET or POST variable with the name of the value of $amount."
The second parameter $default is also very useful:
$amount = JRequest::getVar('amount', 100);
// is roughly equivalent to:
if ($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_GET['amount'])) {
$amount = $_GET['amount'];
} else if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['amount'])) {
$amount = $_POST['amount'];
} else {
$amount = 100;
}
Even without the second parameter though, it'll take care of variable cleaning and (un)escaping where necessary, so it's a good idea to use this function to read request parameters.

getVar gets a variable from one of PHPs global arrays depending on the hash argument passed.
Joomla API
Code

Related

Good practice for referencing returned array values

This is something I haven't seen before but it appears to be supported and it does work, referencing the returned array key directly after the providing function is called. BUT... is this good practice? Will this be supported in the future? Does this even have a name?
<?php
function example_function() {
$return = array('part_1', 'part_2');
return $return;
}
$var = example_function()[0];
echo $var;
To get the same result I would normally do the following
$var = example_function();
$var = $var[0];
It's called Array Dereferencing. It has been available since PHP 5.4. It is acceptable to use although some might say it reduces readability.
Use it only when you are sure that you will always get array to work on. Sometimes ago I've have following code in some scraper class:
$ip = $this->getIP()[0];
I didn't check whether this function could return string and it caused some logic errors. Nowadays each time when I want to get array's item I do
$ip = $this->getIP()
if(is_array($ip)) {
$ip = $ip[0];
} else {
throw new Exception('Expects array here')
}

PHP take string and check if that string exists as a variable

I have an interesting situation. I am using a form that is included on multiple pages (for simplicity and to reduce duplication) and this form in some areas is populated with values from a DB. However, not all of these values will always be present. For instance, I could be doing something to the effect of:
<?php echo set_value('first_name', $first_name); ?>
and this would work fine where the values exist, but $user is not always set, since they may be typing their name in for the first time. Yes you can do isset($first_name) && $first_name inside an if statement (shorthand or regular)
I am trying to write a helper function to check if a variable isset and if it's not null. I would ideally like to do something like varIsset('first_name'), where first_name is an actual variable name $first_name and the function would take in the string, turn it into the intended variable $first_name and check if it's set and not null. If it passes the requirements, then return that variables value (in this case 'test'). If it doesn't pass the requirements, meaining it's not set or is null, then the function would return '{blank}'.
I am using CodeIgniter if that helps, will be switching to Laravel in the somewhat near future. Any help is appreciated. Here is what I've put together so far, but to no avail.
function varIsset($var = '')
{
foreach (get_defined_vars() as $val) {
if ($val == $var) {
if (isset($val) && $val) {
echo $val;
}
break;
}
}
die;
}
Here is an example usage:
<?php
if (varIsset('user_id') == 100) {
// do something
}
?>
I would use arrays and check for array keys myself (or initialize all my variables...), but for your function you could use something like:
function varIsset($var)
{
global $$var;
return isset($$var) && !empty($$var);
}
Check out the manual on variable variables. You need to use global $$var; to get around the scope problem, so it's a bit of a nasty solution. See a working example here.
Edit: If you need the value returned, you could do something like:
function valueVar($var)
{
global $$var;
return (isset($$var) && !empty($$var)) ? $$var : NULL;
}
But to be honest, using variables like that when they might or might not exist seems a bit wrong to me.
It would be a better approach to introduce a context in which you want to search, e.g.:
function varIsset($name, array $context)
{
return !empty($context[$name]);
}
The context is then populated with your database results before rendering takes place. Btw, empty() has a small caveat with the string value "0"; in those cases it might be a better approach to use this logic:
return isset($context[$name]) && strlen($name);
Try:
<?php
function varIsset($string){
global $$string;
return empty($$string) ? 0 : 1;
}
$what = 'good';
echo 'what:'.varIsset('what').'; now:'.varIsset('now');
?>

What is the proper way to initialize empty strings in PHP?

In C#, I've come to adopt the following method of initializing empty strings:
string account = string.empty;
rather than
string account = "";
According to my mentor and other C# developers I've talked to, the first method is the better practice.
That said, is there a better way to initialize empty strings in PHP? Currently, I see the following widely used:
$account = '';
Thanks.
What you're doing is correct. Not much more to say about it.
Example:
$account = '';
if ($condition) $account .= 'Some text';
echo $account;
You could get silly and do something like this:
$str = (string) NULL;
..but that's utterly pointless, and it's exactly the same thing - an empty string.
You're doing it right.
For the most part this is irrelevant. Unlike many languages, in PHP it (usually) doesn't matter whether you initialize a variable. PHP will automatically cast an uninitialized (or even undeclared) variable as appropriate for the immediate use. For example, the following are all correct:
$a;
$a + 7; // Evaluates to 7
$a . "This is a test."; // Evaluates to "This is a test."
if (! $a) {} // Evaluates as true
The one caveat is that select functions check for variable type (as does strict equality checking, ===). For example, the following fails:
$a;
if (is_string($a)) {
print 'success';
}
else {
print 'fail';
}
This convenience comes at a heavy cost, though. Unlike strictly typed (or, at least, "more strictly" typed) languages, there is nothing in the core language itself to help you catch common programmer errors. For example, the following will happily execute, but probably not as expected:
$isLoggedIn = getLoginStatus($user);
if ($isLogedIn) {
// Will never run
showOrder($user);
}
else {
showLoginForm();
}
If you choose to initialize all your variables, do it just as you did. But then enable PHP notices (E_NOTICE) to get run-time warnings about uninitialized variables. If you don't, you're basically wasting time and keystrokes initializing your own variable.
Here are some other things to consider when working with strings in PHP:
// Localize based of possible existence
$account = (array_key_exists('account', $results)) ? $results['account'] : null;
// Check to see if string was actually initialized
return (isset($account)) ? $account : null
// If a function is passed an arg which is REQUIRED then validate it
if (empty($arg1)) {
throw new Exception('Invalid $arg1');
}
echo $arg;
// If you are looking to append to string, then initialize it as you described
$account = null;
if (!empty($firstName)) {
$account .= $firstName;
}
echo $account;
// Also, it's better to initialize as null, so you an do simple check constructs
if (is_null($account)) {
// Do something
}
// Versus these types of checks
if ($account == '') {
// Do something
}
Normally I try to avoid initializing vars like this. Instead I localize, or check for existence throughout the code, otherwise you end up maintaining a laundry list of variables which may not actually reflect usage throughout the code following initialization.
chr(32) represents ASCII space (i.e. string of 1 byte length).
If you want to avoid mistakes like $myEmpty = " " vs. $myEmpty = " " vs. $myEmpty = ""
Sometimes it's hard to tell when there are two spaces or one or none by human eyes. Using chr function that is solved for sure.
And for really empty string (zero bytes), there's no other way but to simply define it with (single) quotation marks like $nothing = '';

Why doesn't my code to test an email address against a specific domain work?

I wanted to allow only specific email domain. Actually I did it. What i wanted to ask why my first code did not work at all.
I am just trying to learn PHP so that the question may seem silly, sorry for that.
Here is my code:
function check_email_address($email) {
$checkmail = print_r (explode("#",$email));
$container = $checkmail[1];
if(strcmp($container, "gmail.com")) {
return true;
}else {
return false;
}
}
Check out the documentation for strcmp() , it will return 0 of the two strings are the same, so that's the check you want to be doing. Also, you're using print_r() when you shouldn't be, as mentioned by the other answerers.
Anyway, here's how I would have done the function - it's much simpler and uses only one line of code:
function check_email_address($email) {
return (strtolower(strstr($email, '#')) == 'gmail.com');
}
It uses the strstr() function and the strtolower() function to get the domain name and change it to lower case, and then it checks if it is gmail.com or not. It then returns the result of that comparison.
It's because you're using print_r. It doesn't do what you seem to expect from it at all. Remove it:
$checkmail = explode("#", $email);
You can find the docs about print_r here:
http://php.net/print_r
Besides that, you can just use the following (it's much shorter):
$parts = explode("#", $email);
return (strcmp($parts[1], "gmail.com") == 0);
The following row doesn't work as you think it does:
$checkmail = print_r (explode("#",$email));
This means that you're trying to assign the return value from print_r() into $checkmail, but it doesn't actually return anything (if you don't supply the second, optional parameter with the value true).
Even then, it would've gotten a string containing the array structure, and your $container would have taken the value r, as it's the second letter in Array.
Bottom line: if your row would've been without the call to print_r(), it would've been working as planned (as long as you made sure to compare the strcmp() versus 0, as it means that the strings are identical).
Edit:
Interesting enough, I just realized that this could be achieved with the use of substr() too:
<?php
//Did we find #gmail.com at the end?
if( strtolower(substr($email, -10)) == '#gmail.com' ) {
//Do something since it's an gmail.com-address
} else {
//Error handling here
}
?>
You want:
if(strcmp($container, "gmail.com")==0)
instead of
if(strcmp($container, "gmail.com"))
Oh! And no inlined print_r() of course.
Even better:
return strcmp($container, "gmail.com")==0;
No need for the print_r; explode returns a list. And in terms of style (at least, my style) no need to assign the Nth element of that list to another variable unless you intend to use it a lot elsewhere. Thus,
$c = explode('#',$mail);
if(strcmp($c[1],'gmail.com') == 0) return true;
return false;

PHP GET Question: How do I set a variable value only if it's not in the query string?

I know how to get the value from the query string if the parameter exists:
$hop = $_GET['hop'];
But I also need to set a default value IF it's not in the query string. I tried this and it didn't work:
$hop = $_GET['hop'];
if ($hop = " ") {
$hop = 'hardvalue';
};
Please help me handle the case where the query string has and does not have the "hop" parameter, and if it's present but not defined:
example.com/?hop=xyz
&
example.com/
&
example.com/?hop=
PS I don't know what I'm doing, so if you explain to me, please also include the exact code for me to add to my PHP page.
use array_key_exists
if (array_key_exists('hop', $_GET))
{
// the key hop was passed on the query string.
// NOTE it still can be empty if it was passed as ?hop=&nextParam=1
}
else
{
//the key hop was not passed on the query string.
}
Thought about it a bit more and decided it should be a bit more robust:
$hop = 'hardvalue';
if (array_key_exists('hop', $_GET)) {
if (!empty($_GET['hop'])) { $hop = $_GET['hop']; }
}
You already got the fiddly solutions. When working with URL or form parameters, you often want to treat the empty string or zeros as absent values too. Then you can use this alternative syntax:
$hop = $_GET["hop"] or $hop = "hardvalue";
It works because of the higher precedence of = over or, and is easier to read with extra spaces.
Starting from PHP 5.3 it's also possible to use:
$hop = $_GET["hop"] ?: "hardvalue";
The advantage here is that this syntax doesn't slurp up php notices, which are useful for debugging.
Actually, I would use
$hop = !empty($_GET['hop']) ? $_GET['hop'] : 'default';
Using empty() instead of isset() takes care of your third scenario, where the parameter is present but not defined.
Also, in if ($hop = " ") the = would need to be changed to ==. = assigns, == tests equality. The way you have it, the if-statement will always run, no matter what $hop equaled.

Categories