In a Laravel 4.2 setup, I have a variable in a template that I wish to share across multiple includes:
master.blade
<?php $tabindex = 0; ?>{{--This is the variable--}}
#include('header'){{-- <-in header.blade, I often use ++$tabindex --}}
{{--$tabindex is still 0--}}
#include('content'){{-- <-in content.blade, I often use ++$tabindex --}}
{{--$tabindex is still 0--}}
#include('footer'){{-- <-in footer.blade, I often use ++$tabindex --}}
{{--$tabindex is still 0--}}
$tabindex if used as a tabindex html attribute is clearly a trivial example that I can get around with safety values and a large enough buffer value, but that's hardly elegant or a solution to the actual problem at hand. In regular php includes, it's my understanding that variable assignment in included files would affect the variables in the including file - this is the desired effect.
I tried View::share(), but it presented the same symptoms. Passing the value to the #include as an array is clearly passing by value and produced the same effect as well.
It almost seems like the including scope values are evaluated first in their entirety, and then the included scopes. If this is the case, it would make what I'm trying to do much less feasible if there is any usage in the including scope or further included scopes (even storing by way of some persisting memory) because the order of execution would be different than the order in the code.
Is there some undocumented blade sorcery to prevent a blade #include from cutting itself off from changing the values of its includer's variables or must I fall back on straight php include or some other ugly alternative (Session variables should persist their values across calling include scopes, but that's just a nasty and flimsy approach)?
Using,
#include('view', array('key'=>'value'))
Would be the best way.
I take it from what you said, that you've been doing something like this.
View::share('some_variable',$some_variable);
And maybe initialized the variable in the template. This practice is discouraged, but there-s another way you can do it, which would be to initialize the variable in a php file and share it from there by adding this line to the file.
$some_variable = 0; //Initialize it any way you need to.
View::share('some_variable', $some_variable);
And then in your app/start/global.php you add this line.
require app_path().'/composers.php';
Laravel blade include seem to create a variable scope for every included template you add.
View:share('name', $value)
Does different thing from what you want, it is intended to inject some arbitrary variables to every template rendered, it's usefull to define assets path in bootstrap or entry point of your controller.
To solve your problem, just tell php in the included scope to look up for a variable above via global, so main.blade.php:
<?php $tabIndex = 0 ?>
#include('subform');
and in templates subform.blade.php
<?php
global $tabindex;
$tabindex++;
?>
Note, this might not work if you define the variable not in a main template, I have tried this only at main template (the one that I render to in controller) and it worked.
Related
I have a PHP page that lists many products that each consist of HTML that -depending on the product- does or does not show certain information. I extracted this "product HTML" into a separate PHP file that I include many times. The external file uses variables for each of the product's attributes and also if statements so that parts of the HTML are not rendered at all when an attribute is not set.
The problem is that many of the attributes have default values that I do not want to set each time I call the include
So is there a mechanism in PHP that lets me include another PHP file in such a way that:
I can provide parameters to the file,
uses a default value for the parameters when I do not provide a value,
can be used multiple times in one file.
(This is the way <jsp:include works.)
Keep in mind that I cannot use simple variables (as far as I know) because they keep their value between two separate include calls.
When you include a file in PHP, that file has access to the current scope. So, we need a "clean" scope with no variables and populate the one we need. The best way to go is using a function and the PHP extract method:
function product($data){
extract($data);
require(....path to file);
}
Now call it:
product(array(
'foo' => 'bar',
....
));
This way, on the included file you got a $foo variable with 'bar' value and nothing else. This is how MVC frameworks deal with views.
Edit:
<?PHP
function product($data){
extract($data);
?>
<HTML content>
<?PHP
}
?>
Now "require_once" the file with this and call it like before.
Let me begin by stating that I know using global variables is not the best practice, this is just a temporary tweak until a more extensive rewrite is completed. That said...
I came across some code that was being duplicated 3 times, like so.
template_1 loads an array, then filters out data, then loads template_part_2. template_part_2 loads the array again and filters out the exact same data, then loads the module_1. module_1 loads the array again and filters out the exact same data as the last two. Resulting in something like this:
include_array.php
function load_array(){
<multidimensional array here>
};
template_1.php
include_once(include_array.php);
$array = load_array();
// code to filter array
include_once(template_1_part_2.php);
template_1_part_2.php
$array = load_array();
// code to filter array
include_once(module_1.php);
module_1.php
$array = load_array();
// code to filter array
This seemed unnecessary to me and a waste of memory, so I changed it to only filter once and then globalize it in the subsequent files like so:
include_array.php
function load_array(){
<multidimensional array here>
};
template_1.php
include_once(include_array.php);
$array = load_array();
// code to filter array
include_once(template_1_part_2.php);
template_1_part_2.php
global $array;
include_once(module_1.php);
module_1.php
global $array;
Now this change saves me 2mb of memory per page load, but the page loads .03 seconds slower. That's about 18% less memory, but loads about 25% slower. I would assume it be more memory efficient and faster since it's doing less processing, but that is not what I'm seeing. I've tried to do some research as to why this is the case but I haven't found anything, can anyone shed some light on this mystery?
Thanks in advance!
I think you don't understand how including a file works in PHP. Basically when you include a file its like the code just gets appended to the one doing the include. Any variable that's defined outside of all functions is automatically accessible to the code (that's outside all functions) from all the files. So only inside functions would you have to use the global keyword to gain access to a global variable. You don't use the global keyword to make a variable from one file accessible in other files: you included the files all into one already so you don't have to do anything special to let them share.
The docs say it like:
When a file is included, the code it contains inherits the variable
scope of the line on which the include occurs. Any variables available
at that line in the calling file will be available within the called
file, from that point forward. However, all functions and classes
defined in the included file have the global scope.
However:
If the include occurs inside a function within the calling file, then
all of the code contained in the called file will behave as though it
had been defined inside that function.
Make your includes global, i.e. outside all functions, and you shouldn't have to jump through all these hoops.
i am very new to php, i am used to writing .net, and i am finding the includes hard to understand and was hoping someone could help me understand how to correctly use an include once in a file, rather than inside each function..
take the following as an example
<?php
include 'test.php';
function test($a)
{
echo $value_from_test_php;
}
?>
the above code does not seem to work... however the below does
<?php
function test($a)
{
include 'test.php'
echo $value_from_test_php;
}
?>
i am having a hard time figuring out how to make an include work for all functions inside a file, rather then including it inside each function, any advice is greatly appreciated!
It's the scope of variable which is troubling you rather than includes, in PHP generally includes are used where there's a common page/markup to be included on each page, such as footer, header, etc
There are 4 types
include
include_once
require
require_once
The only difference is include will throw you an error if something goes wrong and will continue to execute the script where require will halt the further execution
You'll get everything here on includes - PHP Documentation
It all depends what is inside the file that you are include-ing! I would never, ever, suggest using include inside a function (or loop, or pretty much anything with brackets). Remember, the contents of the file being included are literally just "plopped in" place, right where the include statement is. So whatever scope (global, class, function, etc.) you're in when you include, is the scope that its contents will be declared in.
Put full class and function definitions in files, and include them at the top of the files where they are going to be used.
Your issue is not related to includes, but rather variable scope. By default a variable defined outside a function is not available within the function.
It's difficult to suggest the best solution without knowing exactly what it is you're trying to do, but the documentation (linked above) should get you started.
First example is not working because you use variable from global scope, if you want to use it then replace $value_from_test_php to $GLOBALS['my_var_name']
From what I understand using something like require_once will essentially copy and paste the code from one file into another, as if it was in the first file originally.
Meaning if I was to do something like this it would be valid
foo.php
<?php
require_once("bar.php");
?>
bar.php
<?php
print "Hello World!"
?>
running php foo.php will just output "Hello World!"
Now my question is, if I include require_once inside a method, will the file that is included be loaded when the script is loaded, or only when the method is called?.
And if it is only when the method is called, is there any benefit performance wise. Or would it be the same as if I had kept all the code into one big file.
I'm mainly asking as I've created an API file, which handles a large amount of calls, and I wan't to simplify the file. (I know I can do this just be creating separate classes, but I thought this would be good to know)
(Sorry if this has already been asked, I wasn't sure what to search for)
It will only include when the method is called, but have you looked at autoloading?
1) Only when the method is called.
2) I would imagine there's an intangible benefit to loading on the fly so the PHP interpreter doesn't have to parse extra code if it's not being used.
I usually use the include('bar.php'); i use it for when i use databvase information, i have a file called database.php with login info and when the file loads it calls it right up. I don't need to call up the function. It may not be the most effective and efficient but it works for me. You can also use include_once... include basically does what you want it to, it copies the code essencially..
As others have mentioned, yes, it's included just-in-time.
However, watch out for variable definitions (require()ing from a method will only allow access to local variables in that method's scope).
Keep in mind you can also return values (i.e. strings) from the included file, as well as buffer output with ob_start() etc.
I want to define something like this in php:
$EL = "\n<br />\n";
and then use that variable as an "endline" marker all over my site, like this:
echo "Blah blah blah{$EL}";
How do I define $EL once (in only 1 file), include it on every page on my site, and not have to reference it using the (strangely backwards) global $EL; statement in every page function?
Most PHP sites should have a file (I call it a header) that you include on every single page of the site. If you put that first line of code in the header file, then include it like this on every page:
include 'header.php';
you won't have to use the global keyword or anything, the second line of code you wrote should work.
Edit: Oh sorry, that won't work inside functions... now I see your problem.
Edit #2: Ok, take my original advice with the header, but use a define() rather than a variable. Those work inside functions after being included.
Sounds like the job of a constant. See the function define().
Do this
define ('el','\n\<\br/>\n');
save it as el.php
then you can include any files you want to use, i.e
echo 'something'.el; // note I just add el at end of line or in front
Hope this help
NOTE please remove the '\' after < br since I had to put it in or it wont show br tag on the answer...
Are you using PHP5? If you define the __autoload() function and use a class with some constants, you can call them where you need them. The only aggravating thing about this is that you have to type something a little longer, like
MyClass::MY_CONST
The benefit is that if you ever decide to change the way that you handle new lines, you only have to change it in one place.
Of course, a possible negative is that you're calling including an extra function (__autoload()), running that function (when you reference the class), which then loads another file (your class file). That might be more overhead than it's worth.
If I may offer a suggestion, it would be avoiding this sort of echoing that requires echoing tags (like <br />). If you could set up something a little more template-esque, you could handle the nl's without having to explicitly type them. So instead of
echo "Blah Blah Blah\n<br />\n";
try:
<?php
if($condition) {
?>
<p>Blah blah blah
<br />
</p>
<?php
}
?>
It just seems to me like calling up classes or including variables within functions as well as out is a lot of work that doesn't need to be done, and, if at all possible, those sorts of situations are best avoided.
#svec yes this will, you just have to include the file inside the function also. This is how most of my software works.
function myFunc()
{
require 'config.php';
//Variables from config are available now.
}
Another option is to use an object with public static properties. I used to use $GLOBALS but most editors don't auto complete $GLOBALS. Also, un-instantiated classes are available everywhere (because you can instatiate everywhere without telling PHP you are going to use the class). Example:
<?php
class SITE {
public static $el;
}
SITE::$el = "\n<br />\n";
function Test() {
echo SITE::$el;
}
Test();
?>
This will output <br />
This is also easier to deal with than costants as you can put any type of value within the property (array, string, int, etc) whereas constants cannot contain arrays.
This was suggested to my by a user on the PhpEd forums.
svec, use a PHP framework. Just any - there's plenty of them out there.
This is the right way to do it. With framework you have single entry
point for your application, so defining site-wide variables is easy and
natural. Also you don't need to care about including header files nor
checking if user is logged in on every page - decent framework will do
it for you.
See:
Zend framework
CakePHP
Symfony
Kohana
Invest some time in learning one of them and it will pay back very soon.
You can use the auto_prepend_file directive to pre parse a file. Add the directive to your configuration, and point it to a file in your include path. In that file add your constants, global variables, functions or whatever you like.
So if your prepend file contains:
<?php
define('FOO', 'badger');
In another Php file you could access the constant:
echo 'this is my '. FOO;
You might consider using a framework to achieve this. Better still you can use
Include 'functions.php';
require('functions');
Doing OOP is another alternative
IIRC a common solution is a plain file that contains your declarations, that you include in every source file, something like 'constants.inc.php'. There you can define a bunch of application-wide variables that are then imported in every file.
Still, you have to provide the include directive in every single source file you use. I even saw some projects using this technique to provide localizations for several languages. I'd prefer the gettext way, but maybe this variant is easier to work with for the average user.
edit For your problem I recomment the use of $GLOBALS[], see Example #2 for details.
If that's still not applicable, I'd try to digg down PHP5 objects and create a static Singleton that provides needed static constants (http://www.developer.com/lang/php/article.php/3345121)
Sessions are going to be your best bet, if the data is user specific, else just use a conifg file.
config.php:
<?php
$EL = "\n<br />\n";
?>
Then on each page add
require 'config.php'
the you will be able to access $EL on that page.