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']);
}
}
Related
I am having a problem with PHP that's confusing to me
Namely: Notice: Undefined variable: _GET in /var/www/dd.lo/app/libraries/system/input.php on line 86
pops up when you call:
$this->input->get('test');
The function calls another function (If my approach is bad please do not be mad. I will be happy if you tell me how to do it correctly):
public function get ($index)
{
return $this->_getArray('_GET', $index);
}
here is the code of the private function:
private function _getArray ($array, $index)
{
if (isset(${$array}[$index]))
{
return ${$array}[$index];
}
else
{
return NULL;
}
}
The Input class provides convenient access to _POST, _GET, _COOKIE and _SERVER data and allows you to avoid type checking:
if (isset($_POST['name']))
{
$name = $_POST['name'];
}
else
{
$name = NULL;
}
Incidentally, it requests a page at http://dd.lo/?test=dgdsgsdgsdgsd (i.e. $_GET, I asked)
If you write var_dump($_GET); then there is the index 'test'.
Apologies for the English, but I don't speak or read your language (Russian?). This answer is based on Google translate's version of what you asked.
PHP's super globals ($_GET, $_POST, etc.) are special variables, and it looks like you can't use these variables with PHP's variable variable feature. For example, this works
$foo = ['Hello'];
$var_name = 'foo';
var_dump($$var_name);
The "variable variable" $$var_name expands as $'foo'/$foo, and the variable dumps correctly.
However, the following does not work
$var_name = '_GET';
var_dump($$var_name);
It appears that whatever magic scope variable variables live in, that scope doesn't include the super globals. You'll need to rethink your approach. One way you might do this is by accepting the actual array instead of a string that's it's name, and specifying a "by reference" parameter in your function to avoid any performance issues
function _getArray(&$array, $key)
{
if(!is_array($array)) { throw new Exception("Invalid argumnet!");}
if(array_key_exists($key, $array))
{
return $array[$key];
}
return NULL;
}
Upon executing a script, sometimes the variable will be set, and sometimes it won't. The times that it isn't, I'm given a notice that the variable is not defined.
In efforts to clear the notice, I simple added the following code
if(!isset($var)) {
$var = NULL;
}
That works just as needed because it tests if the variable isn't already set so that we don't set something that we need to NULL. But in a file where there are over 60 variables that are of this case and more to come, I thought creating a simple function to do so would be easier. So I started with this:
function init($var) {
if(!isset($var)) {
return $var = NULL;
}
}
Obviously that doesn't work and is also riddled with errors that will annoy most programmers out there (such as the !isset() inside a function, not supplying a return statement in case the if statement is false, etc.) but that's just to give you the basic jist of what I need so in the code I can just call init($var); to test if the variable isn't already set, and then creates one and sets it to NULL to avoid the notice.
Is this even possible? To use a function to test if a variable is already set outside of the function? Thanks in advance :)
You can't use a function to check if a variable exists without it being initialized in the process of passing it to the function as an argument. You can, however, define an array of variable names your script requires then loop through them and check if they exist one by one. Such as:
foreach(array('username','userid','userrole','posts','dob','friends') as $var)
{
if(!isset($$var))$$var=NULL;
}
Edit: Simplifying user4035's approach, you could get the function down to:
<?php
function init(&$var){}
init($myVariable);
var_dump($myVariable);
Or even avoid a function altogether:
<?php
array(&$var1,&$var2,&$var3);//define several variables in one shot as NULL if not already defined.
var_dump($var1);
var_dump($var2);
var_dump($var3);
Another approach would be to use extract:
<?php
$defaults=array('username'=>NULL,'userid'=>0,'userrole'=>'guest','posts'=>0,'dob'=>0,'friends'=>array());
$userid=24334;
$username='bob';
$friends=array(2,5,7);
extract($defaults, EXTR_SKIP);
echo '<pre>';
print_r(
array(
'userid'=>$userid,
'username'=>$username,
'friends'=>$friends,
'userrole'=>$userrole,
'posts'=>$posts,
'dob'=>$dob)
);
echo '</pre>';
Another approach would be to temporarily disable error reporting:
<?php
$v=ini_get("error_reporting");
error_reporting(0);
echo 'One';
echo $doh;//Use an undefined variable
echo ' Two';
error_reporting($v);
I'd advise against this approach though because it is just hiding the errors rather than fixing them and will also hide errors worthy of your attention.
And my personal favorite would be to take advantage of namespaces.
Usually you'd put these into separate files but I put them into a single snippet for your convenience:
<?php
namespace //This is the global namespace
{
$config=array('production'=>0);
}
namespace MyScript
{
//Initialize all variables for our script
//anything not defined here will be inherited from the global namespace
$username=NULL;
$userid=NULL;
$userrole=NULL;
$posts=NULL;
$dob=NULL;
$friends=NULL;
}
namespace MyScript\Main
{
//Define only two variables for our script
//Everything else will be inherited from the parent namespace if not defined
$username='Ultimater';
$userid=4;
echo '<pre>';
print_r(
array(
'userid'=>$userid,
'username'=>$username,
'friends'=>$friends,
'userrole'=>$userrole,
'posts'=>$posts,
'dob'=>$dob,
'config'=>$config)
);
echo '</pre>';
}
If your intention is this:
if(variable is not set)
set variable to NULL
then it's quite easy to implement, using a reference:
function init(&$var) {
if(!isset($var)) {
$var = NULL;
}
}
Testing:
<?php
error_reporting(E_ALL);
function init(&$var) {
if(!isset($var)) {
$var = NULL;
}
}
init($x);
var_dump($x);
Output:
NULL
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 */
I have a function that needs to include a file, however this functions is used in a place from 200 to 300 times, this is obviously causing efficiency issues, is there a way to optimize this inside the function? (i know there are many ways in which i can fix this but it will cause too much impact in the whole application)
I will just put a little example, this is not the whole function.
function getString(arrayName, strValue){
inclue('stringArrays.php');
return $$arrayName[strValue];
}
I tried using include_once, but that doesn't do the job either.
Thanks in advance.
You could use a static variable in the function to hold your values:
function getString($arrayName, $strValue){
static $string_arrays = array();
if (empty($string_arrays)) {
include('stringArrays.php');
$string_arrays = array_diff_key(get_defined_vars(), array(
'string_arrays' => true,
'arrayName' => true,
'strValue' => true,
));
}
return $string_arrays[$arrayName][$strValue];
}
Should only include the file once.
You could always add another parameter, perhaps a boolean, to tell the function whether or not to include it.
function getString(arrayName, strValue, includeFile)
{
if (includeFile)
{
inclue('stringArrays.php');
}
return $$arrayName[strValue];
}
You can try globalizing what's in stringArrays.php so you can check to see if that global variable is already set before including the file. Hard to tell without seeing what structure is in stringArrays.php.
If your function does nothing more than include a file you should be first evaluating whether that function should be called in the first place or make the function determine if an include is required. Basically don't blindly include a file if you truly don't need it included. include_once will incur a performance hit.
Install APC, eAccelerator, XCache or any other code accelerator so PHP doesn't need to retrieve the include file from disk every time it's called. Code accelerators save the file in shared memory. That will improve performance significantly.
Is there anything preventing you from wrapping your current "bunch" of arrays in an array, then passing that wrapper array into the function by reference? You can then do a single require/include outside of the function. Alternatively, you can wrap both the set of arrays and the function inside an object, again bringing you down to a single require/include.
If stringArrays.php is simply a collection of arrays, what about creating a stringHandler singleton that includes stringArrays.php within the constructor and maps the each array to a class property, then a simple method to get whichever you want from that class. Then your getString() function simply references a getter method in the stringHandler.
stringArrays.php
<?php
$abc = array('def' => 'Hello',
'ghi' => ' '
);
$jkl = array('mno' => 'World',
'pqr' => '.'
);
?>
stringHandler.php
<?php
class stringHandler
{
private static $instance;
private function __construct()
{
include('stringArrays.php');
foreach(get_defined_vars() as $key => $val) {
$this->{$key} = $val;
}
}
public static function singleton()
{
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
}
public function getStringFromArray($arrayName, $strValue)
{
return $this->{$arrayName}[$strValue];
}
}
function getString($arrayName, $strValue){
return stringHandler::singleton()->getStringFromArray($arrayName, $strValue);
}
echo getString('abc','def');
echo getString('abc','ghi');
echo getString('jkl','mno');
?>
Kludgy, but shouldn't be a big performance overhead.
I have this in my class
When the second function is called php errors with
wrong datatype and only variables can be past by reference.
I don't know what they mean by that
This code comes from php.net
If the same code is outside the class it executes fine
What am I doing wrong here, if I am working within a class?
$extensiesAllowed= array();
function __construct() {
$this->extensiesAllowed= array("txt", "pdf");
$this->fileName= $_FILES['file'];
}
private function isAllowedExtensie($fileName) {
return in_array(end(explode(".", $fileName)), $this->extensiesAllowed);
}
public function check_upload() {
if($this->fileName['error'] == UPLOAD_ERR_OK) {
if(isAllowedExtensie($this->fileName['name'])) {
return true;
}
}
}
the php error shows
Array
(
[bestandsNaam] => ACCOUNT INFO.txt
[extensiesAllowed] =>
)
Thanks, Richard
try putting the end and explode in seperate statements - I think end() may read by reference. In any case, it will help you figure out what line is causing you problems if it doesnt fix it.
In the second function/method you should call should be calling isAllowedExtensie as $this-> isAllowedExtensie()
if($this->isAllowedExtensie($this->fileName['name'])) {
Edit: forget my second comment..