i have a question in PHP related to the parameters of a function and their scope.
I am building an own little template system and currently i keep using:
try {
$ret = include("file.php");
if(!$ret) {
throw new Exception();
}
// Go on here...
}
catch(Exception $e) {
// error handling
}
about 3-4 times in the mainfile index.php. This code first includes the needed file (set by GET parameters in the URL), trys to include it and if it fails it handles all errors. Since this is used 3-4 times in index.php i want to make a function out of it so i can easily call $Template->LoadFile("filename.php"); and this function handles everything for me: Including, Executing the code and error handling.
Not that hard i thought, but when doing so i get a lot of error messages because the variables needed by the included file for its execution are only avaiable in the scope of index.php (where the code was executed before) and not in the scope of the LoadFile() function. What can i do now?
Revert everything back and again use this above code 3-4 times stupidly?
Add all needed variables in LoadFile() as parameters so by using $Template->LoadFile($file,$vars); $vars would be available for use in LoadFile() for the included File? By doing so the given parameters would be huge in some cases. For example if i add an own board, the $vars would contain every board data and thats quite much. Wouldn't that make the template system really slow?
Add the needed variables via parameters as reference? (same as my 2nd suggest, but with less engine slowdown).
use globals? NO!
What options are there else? Thank's a lot :)
You can use option2 but in variety of other ways, have a look at how codeigniter and kohana render their views.
you can do something like
$Template->LoadFile($file, $vars)
where $vars is an array like array('thisIsVariableName' => 'thisIsVariableValue')
or
$Template->file($file)
->vars('thisIsVariableName', thisIsVariableValue)
->multi_var(array('thisIsVariableName2' => 'thisIsVariableValue2'))
->render();
In case of the template size, then you can always split a template into subtemplates.
Related
I wrote a small framework, but I am studying others. They are big, so I'm still trying to grasp their design.
When a user calls the controller or router, is call_user_func_array the typical way the page is "handed off" to the renderer?
I tend to see this type of thing which is what I did in mine. It looks like this is what it does in Codeigniter, but I am not sure.
if ((int)method_exists($controller, $action)) {
call_user_func_array(array($dispatch,$action),$queryString);
} else {
/* Error Generation Code Here */
}
I saw this in CodeIgniter:
// Execute the callback using the values in matches as its parameters.
$val = call_user_func_array($val, $matches);
The call_user_func_array() function is used for when you don't know the function you are calling ahead of time. This is why most of the time, the parameters inside are variables.
If you know what function you want to call, always call it manually, otherwise, use this php in-built function.
You should look at the PHP documentation: http://php.net/manual/en/function.call-user-func-array.php
Also another stack overflow question sort of answers this:
PHP call_user_func vs. just calling function
I am struggling to understand scope and what's preventing my new code from working (assuming it is a scope issue).
The following function is in a file PATH.'/includes/custom-functions.php' that references a class:
function infusion() {
require_once(PATH.'/classes/infusion.php'); //PATH is defined in WordPress from ~/wp-content/themes/theme/
return new infusion();
}
The class is reliant on PATH.'/api/isdk.php' and connection credentials from another file within /api/ directory. From within PATH .'/includes/custom-functions.php', I have many other functions that call $infusion = infusion(); and work perfectly.
PROBLEM
I have created a new file: PATH.'/includes/report.php' which I need to access $infusion = infusion();but can't get to work by either repeating the function infusion() definition from above; using require_once();; or using include();. All 3 of those options simply kill the rest of the code and I can only come to the conclusion - well, I have no conclusion.
Any help would be greatly appreciated.
I'm assuming the code isn't using namespaces, therefore you aren't permitted to redeclare the infusion function (either by redefining the function, or re-including the class).
Your includes/report.php file should simply have:
require_once PATH.'/includes/custom-functions.php';
// your other code here ...
$infusion = infusion();
It may be the case that other files / classes that you're including in your file are already requiring custom-functions.php along the line, so you may be able to skip that entirely. Also note that the PATH constant should have already been defined somewhere (either directly or via an included file) before you attempt to use it. If you set your error_reporting to include E_ALL, you'll get a notification in your error log if that constant doesn't exist.
If that fails, your error log(s) may provide some additional background on what your issue is.
In order to localize strings used within my javascript, I want scan all my js files for such strings.
I am using a t() function to request string translations as follows:
t("Hello world");
or with dynamic portions:
t("Hello #user", {"#user": "d_inevitable"});
I want to detect all calls to the t() function and thus gather the strings contained in the first argument in a php "build" script, but skipping the following:
function foo(t) {
t("This is not the real t, do not localize this!");
}
function bar() {
var t = function(){}; //not the real t either...
}
function zoo() {
function t() {
//This also isn't the real t() function.
}
}
t("Translate this string, because this is the real t() in its global scope");
So the simple rule here is that the t function being invokes must be in global scope in order for the first argument to qualify as a translation string.
As a rule, dynamic runtime data as first argument is not allowed. The first argument to t() must always be a "constant" literal string.
I think php codesniffer will help me do it, however all the documentation I could find on it is about enforcing code standard (or detecting violations of it). I need lower level access to its js lexer.
My question is:
Would the php codesniffer's js lexer be able to help me solve my problem?
If so how do I access that lexer?
Are there any other php libs that could help me find the calls to t()?
Please do not suggest stand-alone regular expressions as they cannot possibly solve my problem in full.
Thank you in advance.
What you are describing is basically a coding standard. Certainly, ensuring strings are localised correctly is part of many project standards. So I think PHPCS is the right tool for you, but you will need to write a custom sniff for it because nothing exists to do exactly what you are after.
The best thing to do is probably clone the PHPCS Git repo from Github and then create a new directory under CodeSniffer/Standards to contain your custom sniff. Let's say you call it MyStandard. Make sure you create a Sniffs directory under it and then a subdirectory to house your new sniff. Take a look at the other standards in there to see how they work. You'll also find it easier to copy an existing ruleset.xml file from another standard and just change the cotent to suit you. if you don't want to include any other sniffs from anywhere (you just want to run this one check over your code) then you can just specify a name and description and leave the rest blank.
There is a basic tutorial that covers that.
Inside your sniff, you'll obviously want it to check JS files only, so make sure you specify that in the supportedTokenizers member var (also in the docs). This will ensure PHP and CSS files are always ignored.
When you get down to the actual checking, you'll have full low-level access to the parsed and tokenised content of your file. There are a lot of helper functions to check things like if the code inside other scopes, or to help you move backwards and forwards through the stack looking for bits of code you need.
TIP: run PHPCS using the -v option to see the token output on your file. It should help you see the structure more easily.
If you want to really do things properly, you can even create a nice unit test for your sniff to make sure it keeps running over time.
After all this, you'd check your code like this:
phpcs --standard=MyStandard /path/to/code
And you can use a lot of integrations that exist for PHPCS inside code editors.
You might decide to add a new more sniffs to the standard to check other things, which you can then do easily using your ruleset.xml file or by writing more custom sniff classes.
I hope that helps a bit. If you do decide to write your own sniff and need help, just let me know.
I got a PHP web service that had been running great for a long time, but somewhere a long the way it some how stopped working, and I just can't get it to work again.
I got some php page in which all I do is define a class with functions, and in the end of it I create the SoapServer.
It looks like this -
class MyClassWS
{
function .....
function ....
}
ini_set("soap.wsdl_cache_enabled", "0");
error_log("Server after ini_set");
$soapserver = new SoapServer("MyWSDL.wsdl");
error_log("Server after new SoapServer");
$soapserver->setClass("MyClassWS");
error_log("Server after setClass");
//error_log(print_r($soapserver->getFunctions()));
try
{
$soapserver->handle();
}
catch(Exception $ex)
{
error_log("Exception!".$ex->getMessage());
}
error_log("Finished Handling",0);
Right after the $soapserver->handle(); the code terminates, and I get a vague "SOAP-ENV:ClientBad Request" result on my web page.
This happens when I "require_once" this page, from my index page, so I could call functions that are defined in this class, from my index page.
My guess is that maybe I've been fiddling too much with my WSDL and somehow it screwed up my while WebService, but I tried looking on what's wrong with it, but couldn't get onto anything. Especially because of this annoying vague error message, that doesn't really help.
Thanks!
I think I nicely fixed it by separating the WebService class that included the SoapServer into 2 different classes.
One that included only the class with the functions, and another that included the WebServer and only had a reference to the class.
This way I can import the class with the functions without also importing the SoapServer and triggering the handle() function.
I have a project based on codeigniter. And I should use one class that extended from a codeigniter controller in another php file. But I didn't find the solution about how to teach another php file to see whole CI-project. Beyond that needed class can not inherit when i call it from other place.
I'm not 100% sure if this helps get you in the right direction, but kudos if it does!
Codeigniter routes the application depending on the environment state of the URI. What you need to do is set the environment and include the index view file like so:
$_SERVER["REQUEST_URI"] = "cms/2";
//Set GET action,method params etc
require_once "path/to/index.php";
When you load CI Index file it reads the SERVER Variable and others which you may have to find and execute the controller and method, I would also advise that you modify the library/view file as it may exit upon output causing your script to exit.
Also you may wis hto look into ob_start() to catch the buffer.