I've tried regular functions and call_user_function, both which do not finish executing before they get to the next line after a function call. What do people use instead? Should I just include a separate php file for every "function" I want to run?
edit:
$IDNum = 0;
$restartButtonIDName;
$playButtonIDName;
$audioPlayerIDName;
$MP3AudioSourceIDName;
$OGGAudioSourceIDName;
$resultingTextIDName;
$currentTimeIDName;
$checkOffsetIDName;
call_user_func('setIDNames');
function setIDNames() {
echo "called setIDNames <br />";
call_user_func('incIDNums');
$restartButtonIDName = "restartButton".$IDNum;
$playButtonIDName = "playButton".$IDNum;
$audioPlayerIDName = "audioPlayer".$IDNum;
$MP3AudioSourceIDName = "MP3AudioSource".$IDNum;
$OGGAudioSourceIDName = "OGGAudioSource".$IDNum;
$resultingTextIDName = "resultingText".$IDNum;
$currentTimeIDName = "currentTime".$IDNum;
$checkOffsetIDName = "checkOffset".$IDNum;
}
function incIDNums(){
echo "called setIDNums <br />";
$IDNum += 1;
}
echo $restartButtonIDName." test<br />"; // echos "test" not the resulting name
?>
Variables accessed inside a function are not the same as variables outside the function, or in a different function, unless you declare the variables with a global statement inside the function.
$IDNum = 0;
incIDNums();
echo $IDNum; // Will echo 1
function incIDNums(){
global $IDNum;
echo "called setIDNums <br />";
$IDNum += 1;
}
It's generally considered poor style to depend heavily on global variables, as it impairs the generality of the functions. The function should get its input via parameters, and sends the results as a value using return. If you need to return multiple results, you can package them into an array, or use reference parameters that are updated in place.
Probably the problem you have is due to the scope of variables ,please note the lifetime of variables inside a function is only until function is active to make changes effect to global variables which are outside of function you need to make them global inside function like:
function setIDNames() {
global $restartButtonIDName ,$playButtonIDName ,$audioPlayerIDName ...;//All variables you wanna use saperated by comma.
//Your code
}
Related
Im trying to put these if statements inside a php function to get results. So far its not working. I know this may be an easy solution, but I am new to PHP and the other examples that I looked at didnt help me a lot.
FUNCTION
$startdate='';
$enddate='12/3/2020';
function startEnd($startdate,$enddate){
if($startdate==''){
$startdate='Anytime';
}
if($enddate==''){
$enddate='Anytime';
}
}
CALL
startEnd($startdate,$enddate);
echo $startdate;
echo $enddate;
You cannot use variables that are outside of the scope of the function.
Once it is passed as an argument, in the function, it will be treated as a completely new variable. Unless you reintroduce them to the scope with global.
You can, however, pass a reference of a variable to a function using the & operator in the parameters.
function startEnd(&$string1, &$string2) {
if ($string1 === '') {
$string1 = 'Anytime';
}
if ($string2 === '') {
$string2 = 'Anytime';
}
}
startEnd($startdate, $enddate);
I have this code:
if(!isset($_GET["act"]))
{
$display->display("templates/install_main.html");
if(isset($_POST["proceed"]))
{
$prefix = $_POST["prefix"];
}
}
if($_GET["act"] == "act")
{
echo $prefix;
}
Basically I've made a similar question before, thing is, HOW can I make the variable accessible? please mention if there is any way to do so, even with changing the way it's done (someone told me it's possible with a class but not quite sure how it can be done), or any other way to make it accessible.
Thanks!
PHP's variable scope is function-level. $prefix would be available in your second if() IF the other if()'s evaluated to true and actually executed that $prefix = ... code.
e.g.
if (true) {
$foo = 'bar'; // always executes
}
if (false) {
$baz = 'qux'; // never executes
}
echo $foo; // works just fine
echo $baz; // undefined variable, because $baz='qux' never executed.
Also note that PHP is not capable of time travel:
echo $x; // undefined variable;
$x = 'y';
echo $y; // spits out 'y'
"earlier" code will not have "later" variables available, because the code that actually creates/assigns values to those variables won't have executed yet.
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 any way to do this / specify this in the php.ini configuration file? It would be really nice, at least for local server purposes, just to write functions without having to write the global keyword every time a global variable is used within the method.
Any way to do this?
EDIT:
What I mean is being to simply write this:
Example file "index.php":
$MY_ARRAY = array();
include("functions.php");
And then in "functions.php":
function addToArray($pMessage) {
$MY_ARRAY[] = "<a href='somelink.php'>$pMessage</a>";
}
Instead of:
And then in "functions.php":
function addToArray($pMessage) {
global $MY_ARRAY;
$MY_ARRAY[] = "<a href='somelink.php'>$pMessage</a>";
}
Yeah! You can setup a prepend file in PHP.
See: http://www.php.net/manual/en/ini.core.php#ini.auto-prepend-file
I still do not understand the purpose. But if I need to just remove the GLOBAL keyword from mentioning everytime, I would prefer to use a class with static array.
Something like this:
<?php
// Config.php
class Config {
public static $MY_ARRAY = array();
}
?>
And then include this file from your loader just call like this:
function addToArray($pMessage) {
Config::$MY_ARRAY[] = "<a href='somelink.php'>$pMessage</a>";
}
That will work.
So the senario is that I want to have a custom function for requiring libraries. Something like:
define('E_ROOT', str_replace('//','/',dirname(__FILE__)));
/* ... */
function e_load($fn, $allowReloading = FALSE) {
$inc = E_ROOT.'/path/here/'.$fn.'.php';
if($allowReloading)
require $inc; // !!!
else
require_once $inc; // !!!
}
The problem being that require and require_once will load the files into the namespace of the function, which doesn't help for libraries of functions, classes, et cetera. So is there a way to do this?
(Something avoiding require and require_once altogether is fine, as long as it doesn't use eval since it's banned on so many hosts.)
Thanks!
Technically include() is meant to act as though you're inserting the text of included script at that point in your PHP. Thus:
includeMe.php:
<?php
$test = "Hello, World!";
?>
includeIt.php:
<?php
include('includeMe.php');
echo $test;
?>
Should be the exact same as:
<?php
/* INSERTED FROM includeMe.php */
$test = "Hello, World!";
/* END INSERTED PORTION */
echo $test;
?>
Realizing this, the idea of making a function for dynamically including files makes about as much sense (and is about as easy to do) as having dynamic code all-together. It's possible, but it will involve a lot of meta-variables.
I'd look into Variable Variables in PHP as well as the get_defined_vars function for bringing variables into the global scope. This could be done with something like:
<?php
define('E_ROOT', str_replace('//','/',dirname(__FILE__)));
/* ... */
function e_load($fn, $allowReloading = FALSE) {
$prev_defined_vars = get_defined_vars();
$inc = E_ROOT.'/path/here/'.$fn.'.php';
if($allowReloading)
require $inc; // !!!
else
require_once $inc; // !!!
$now_defined_vars = get_defined_vars();
$new_vars = array_diff($now_defined_vars, $prev_defined_vars);
for($i = 0; $i < count($new_vars); $i++){
// Pull new variables into the global scope
global $$newvars[$i];
}
}
?>
It may be more convenient to just use require() and require_once() in place of e_load()
Note that functions and constants should always be in the global scope, so no matter where they are defined they should be callable from anywhere in your code.
The one exception to this is functions defined within a class. These are only callable within the namespace of the class.
EDIT:
I just tested this myself. Functions are declared in the global scope. I ran the following code:
<?php
function test(){
function test2(){
echo "Test2 was called!";
}
}
//test2(); <-- failed
test();
test2(); // <-- succeeded this time
?>
So the function was only defined after test() had been run, but the function was then callable from outside of test(). Therefore the only thing you should need to pull into the global scope are your variables, via the script I provided earlier.
require_once E_ROOT.$libName.'.php';
KISS
Instead of doing this...
$test = "Hello, World!";
... you could consider doing this ...
$GLOBALS[ 'test' ] = "Hello, World!";
Which is safe and consistent in both local function context, and global include context. Probably not harmful to visually remind the reader that you are expecting $test to become global. If you have a large number of globals being dragged in by your libraries maybe there's justification for wrapping it in a class (then you have the benefit of spl_autoload_register which kind of does what you are doing anyhow).