I do one request and my URL has a parameter like this .../index.php?customer=abc
In index.php's class $_GET['customer'] is available.
There are multiple other classes being created then.
Finally in somefile.php containing some different class someClass, $_GET['customer'] is no more available.
I am forced to use a framework that uses a form that eval()s PHP code on button click.
new TDynButton($body, "login", ... , "\$this->win->doLogin();");
IndoLogin() there is no $_GET['customer']. Cannot understand why. Is it possible if this framework uses action=GET in the background that I am losing my $_GET? Im totally lost.
Thanks.
My approach would be to give the information in $_GET['customer'] to the instatiated object by passing it in the constructor and store it in a private member. This way you have the information needed and no direct access to $_GET is nessessary. This is anyway a better design I think.
$_GET is a global variable that will be available throughout the script you use it in. You have to pass it to the script, though - such as somefile.php?customer=peter
Yes, $_GET is a superglobal variable that is available in all PHP scripts.
And yes, generally, framework convert/sanitaze the GET/POST arrays and clears them.
Related
I am new to codeigniter , In my program i want a variable need to be accessed by multiple controllers,
It's not a constant variable, value of variable changes ,
Sorry , My mistake
I want to store a JSON object to be precise
Pls help me to figure this out.
Thanks in advance.
You can create a base controller with an attribute for your variable, then have your controllers extend that base controller.
Option 1
Since you are using CodeIgniter and sessions then something like this could work out for you:
set it
$someJSONobject = 'JSON';
$this->session->set_userdata('GLOBAL_JSON', $someJSONobject);
retrieve it
$someJSONobject = $this->session->userdata('GLOBAL_JSON');
echo $someJSONobject->subitem;
Make sure you are storing sessions in a DB if you go with this option because Cookie space is VERY limited
Option 2
Even if you are not using CodeIgniters' session implementation then you can do something quite similar in native PHP:
$someJSONobject = 'JSON';
$_SESSION['GLOBAL_JSON'] = $someJSONobject;
Appending on Rooneyl's solution you may want to save that value on session which is easier to access from all end
Session docs
Is it possible to store an anonymous function in a session var and use it later on?
For instance:
$func = "echo $str;";
$_SESSION['myfunc'] = create_function('$str',$func);
When I call $_SESSION['myfunc']('Hello') it works fine on the page it is created in. When called in another page however, I get the error
Call to undefined function()
The other session-vars are available, so that's not the problem. In the session data I see a reference to a lambda, but I can't get it to work.
You can't store an actual function in a session variable - the variable that you're storing in the session needs to be serializable, and lambdas are not. Plus, this seems like a very convoluted thing to do.
Why not store the name of the function that you want to call, and then execute it that way? Or, if you really want to achieve this, you could store the function string in the session, then create the function after the session is restarted.
However, there's almost certainly a better way of achieving what you want.
There is a library allowing to serialize closures: https://github.com/jeremeamia/super_closure
This might allow you to store a closure in a session.
Not sure it's a good idea, though.
The very reason that you would like to store a function in a session variable means that you're doing something wrong. What is the intention of this strategy from your side?
Zend Framework 1 had a very simple way of parsing URL routes and setting found params in the $_GET superglobal for easy access. Sure, you could use ->getParam($something) inside the controller, but if the param was found in the URL, it was also accessible via $_GET.
Example for url mypage.com/mymodule/mycontroller/myaction/someparam/5:
ZF1
$this->getParam('someparam'); // 5
$_GET['someparam']; // 5
ZF2
$this->getEvent()->getRouteMatch()->getParam('someparam'); // 5
$_GET['someparam'] // undefined index someparam
Obviously, the difference is that ZF2 does NOT put the route params into the $_GET superglobal.
How do I make it put the parsed parameters into the $_GET superglobal, since extending the controller and just defining a constructor that does that is out of the question (because RouteMatch is not an object yet and cannot be called from the controller's constructor)?
Calling $_GET = $this->getEvent()->getRouteMatch()->getParam('someparam'); in every one of my controllers would work, but I don't want that.
In other words, following the example URL from above, I want to be able to do $_GET['someparam'] and still get the value "5" in any component in the application.
Edit: Looks like I wasn't clear enough, so I'll try to clarify some more. I want whatever param I enter in the URL via /key/value formation to be available in $_GET instantly. I don't really have a problem with getting the param, I know how to get it and I extended Zend's controller so I can just call $this->getParams again like in ZF1, and now all controllers extend that one, I just want the params from the URL to automatically be in $_GET as well, so I can access them easily in third party components which use $_GET natively.
Edit 2: Updated as reaction to Samuel Herzog's answer:
I don't really mind invalidating the SRP in this case, because the libraries are built in such a way that they need direct access to $_GET - they do their own filtering and directly depend on this superglobal. They also directly fetch $_FILES and $_POST for processing, it's just the way their code works.
I've made the following method in the abstract controller:
$this->mergeGet(); which basically makes $_GET absorb all the route matched params and everything works as intended, but seeing as the libraries will be required in every controller/action, it might get tedious to call that method every time. If only the controller had an init() method like in ZF1...
In ZF2, Im using this
$getparams = $this->getRequest()->getQuery();
First of all, you shouldn't use $_GET or any other superglobal directly if you're building on an object oriented stack. The SRP is invalidated this way.
If you have no possibility to change the way of your (3rd party?) librarys to change you might want to hook into the MvcEvent, listen to --event-- and then get the RouteMatch, you may fill $_GET with a simple loop.
For a most-performant answer, you should know if the named library will be needed for every action, just for one module, or only in certain controllers/actions.
If the latest is your use-case, you should write a controller plugin instead.
some example code for the first approach:
namespace YourModule;
use Zend\EventManager\EventInterface as Event;
use Zend\Mvc\MvcEvent;
class Module
{
...
public function onBootstrap(Event $ev)
{
$application = $e->getApplication();
$eventManager = $application->getEventManager();
$eventManager->attach('route', function(MvcEvent $mvcEvent) {
$params = $mvcEvent->getRouteMatch()->getParams();
foreach ( $params as $name => $value )
{
if ( ! isset($_GET[$name])
{
$_GET[$name] = $value;
}
}
});
}
}
You could use in your controlller:
$paramValue = $this->params()->fromQuery('your_param_here');
Regards
So, I don't come from a huge PHP background—and I was wondering if in well formed code, one should use the 'superglobals' directly, e.g. in the middle of some function say $_SESSION['x'] = 'y'; or if, like I'd normally do with variables, it's better to send them as arguments that can be used from there, e.g:
class Doer {
private $sess;
public function __construct(&$sess) {
$this->sess =& $sess;
}
}
$doer = new Doer($_SESSION);
and then use the Doer->sess version from within Doer and such. (The advantage of this method is that it makes clear that Doer uses $_SESSION.)
What's the accepted PHP design approach for this problem?
I do like to wrap $_SESSION, $_POST, $_GET, and $_COOKIE into OOP structures.
I use this method to centralize code that handles sanitation and validation, all of the necessary isset () checks, nonces, setcookie parameters, etc. It also allows client code to be more readable (and gives me the illusion that it's more maintainable).
It may be difficult to enforce use of this kind of structure, especially if there are multiple coders. With $_GET, $_POST, and $_COOKIE (I believe), your initialization code can copy the data, then destroy the superglobal. Maybe a clever destructor could make this possible with $_SESSION (wipe $_SESSION on load, write it back in the destructor), though I haven't tried.
I don't usually use any of these enforcement techniques, though. After getting used to it, seeing $_SESSION in code outside the session class just looks strange, and I mostly work solo.
EDIT
Here's some sample client code, in case it helps somebody. I'm sure looking at any of the major frameworks would give you better ideas...
$post = Post::load ();
$post->numeric ('member_age');
$post->email ('member_email');
$post->match ('/regex/','member_field');
$post->required ('member_first_name','member_email');
$post->inSet ('member_status',array('unemployed','retired','part-time','full-time'));
$post->money ('member_salary');
$post->register ('member_last_name'); // no specific requirements, but we want access
if ($post->isValid())
{
// do good stuff
$firstName = $post->member_first_name;
}
else
{
// do error stuff
}
Post and its friends all derive from a base class that implements the core validation code, adding their own specific functionality like form tokens, session cookie configuration, whatever.
Internally, the class holds a collection of valid data that's extracted from $_POST as the validation methods are called, then returns them as properties using a magic __get method. Failed fields can't be accessed this way. My validation methods (except required) don't fail on empty fields, and many of them use func_get_args to allow them to operate on multiple fields at once. Some of the methods (like money) automatically translate the data into custom value types.
In the error case, I have a way to transform the data into a format that can be saved in the session and used to pre-populate the form and highlight errors after redirecting to the original form.
One way to improve on this would be to store the validation info in a Form class that's used to render the form and power client-side validation, as well as cleaning the data after submission.
Modifying the contents of the superglobals is considered poor practice. While there's nothing really wrong with it, especially if the code is 100% under your control, it can lead to unexpected side effects, especially when you consider mixed-source code. For instance, if you do something like this:
$_POST['someval'] = mysql_real_escape_string($_POST['someval']);
you might expect that everywhere PHP makes that 'someval' available would also get changed, but this is not the case. The copy in $_REQUEST['someval'] will be unchanged and still the original "unsafe" version. This could lead to an unintentional injection vulnerability if you do all your escaping on $_POST, but a later library uses $_REQUEST and assumes it's been escaped already.
As such, even if you can modify them, it's best to treat the superglobals as read-only. If you have to mess with the values, maintain your own parallel copies and do whatever wrappers/access methods required to maintain that copy.
I know this question is old but I'd like to add an answer.
mario's classes to handle the inputs is awesome.
I much prefer wrapping the superglobals in some way. It can make your code MUCH easier to read and lead to better maintainability.
For example, there is some code at my current job the I hate! The session variables are used so heavily that you can't realistically change the implementation without drastically affecting the whole site.
For example,
Let's say you created a Session class specific to your application.
class Session
{
//some nice code
}
You could write something like the following
$session = new Session();
if( $session->isLoggedIn() )
{
//do some stuff
}
As opposed to this
if( $_SESSION['logged'] == true )
{
//do some stuff
}
This seems a little trivial but it's a big deal to me. Say that sometime in the future I decide that I want to change the name of the index from 'logged' to 'loggedIn'.
I now have to go to every place in the app that the session variable is used to change this. Or, I can leave it and find someway to maintain both variables.
Or what if I want to check that that user is an admin user and is logged in? I might end up checking two different variables in the session for this. But, instead I could encapsulate it into one method and shorten my code.
This helps other programmers looking at your code because it becomes easier to read and they don't have to 'think' about it as much when they look at the code. They can go to the method and see that there is only ONE way to have a logged in user. It helps you too because if you wanted to make the 'logged' in check more complex you only have to go to one place to change it instead of trying to do global finds with your IDE and trying to change it that way.
Again, this is a trivial example but depending on how you use the session this route of using methods and classes to protect access could make your life much easier to live.
I would not recommend at all passing superglobal by reference. In your class, it's unclear that what you are modifying is a session variable. Also, keep in mind that $_SESSION is available everywhere outside your class. It's so wrong from a object oriented point of view to be able to modify a variable inside a class from outside that class by modifying a variable that is not related to the class. Having public attribute is consider to be a bad practice, this is even worst.
I found my way here while researching for my new PHP framework.
Validating input is REALLY important. But still, I do often find myself falling back to code like this:
function get( $key, $default=FALSE ){
return (isset($_GET[$key]) ? $_GET[$key]:$default);
}
function post( $key, $default=FALSE ){
return (isset($_POST[$key]) ? $_POST[$key]:$default);
}
function session( $key, $default=FALSE ){
return (isset($_SESSION[$key]) ? $_SESSION[$key]:$default);
}
Which I then use like this:
$page = get('p', 'start');
$first_name = post('first_name');
$last_name = post('last_name');
$age = post('age', -1);
I have found that since I have wildly different requirements for validation for different projects, any class to handle all cases would have to be incredibly large and complex. So instead I write validation code with vanilla PHP.
This is not good use of PHP.
get $_SESSION variables directly:
$id = $_SESSION['id'];
$hash = $_SESSION['hash'];
etc.
I am using the Zend framework and what I need is to construct a url in my view. Normally in regular php code I'd just grab the GET Variable by using the global $_GET. However with Zend I'm setting it to clean URIs so :
?ac=list&filter=works&page=2
Looks like
index/ac/list/filter/works/page/2
In my view I'm setting a links cs such that if the GET variable filter equals works then the color of that link would be different and it would point to the same page only linked as so:
index/ac/list/filter/extra/page/2
And like wise I have a number of other links all which just one GET value - how do I set this up - I am using the Zend framework.
To access a request variable direct in the view you could do:
Zend_Controller_Front::getInstance()->getRequest()->getParam('key');
But as others have said, this is not a good idea. It may be easier, but consider other options:
set the view variable in the controller
write a view helper that pulls the variable from the request object
If you need to access a GET parameter from a view, i think you're doing it the wrong way.
I suggest that you set up a route with all your parameters, and then use $this->url from your view to render a valid and correct url.
Fore som more info, check out the following blog post (no, i'm not the author):
http://naneau.nl/2007/07/08/use-the-url-view-helper-please/
Edit:
If you want to be 'lazy', you can set a view parameter from your controller by doing $this->view->param = $this->_getParam('param'). You can then access param from your view by doing echo $this->param;. However, i do not recommend this.
To access the Request Object one way that is common is to save it in the Registry.
http://osdir.com/ml/php.zend.framework.mvc/2007-08/msg00158.html
http://www.zfforums.com/zend-framework-components-13/model-view-controller-mvc-21/how-access-request-object-customizing-layout-view-3349.html
You can pass it in from a controller: $this->view->page = $this->_getParam('page');.
Footnote: I agree with #alexn.
i am using Zend Framework v1.11 and i am doing like this
In Controller
$this->view->request = $this->_request;
then in View you can access any Request param like this
<h3><?= $this->request->fullname ?></h3>