SitePoint Sponsor

User Tag List

Page 1 of 3 123 LastLast
Results 1 to 25 of 63

Thread: Request wrapper

  1. #1
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Request wrapper

    I have implemented a request wrapper for an application I'm building which is currenty works like this:

    $request->get('name');
    $request->get('name', 'post');
    $request->get('country_id', 'get');
    $request->get('HTTP_HOST', 'server');

    I'm wondering which is the best way. It could also be done like this:

    $request->getPost('name');
    $request->getGet('country_id');
    $request->getServer('HTTP_HOST');

    or:

    $post =& $request->get('post');
    $get =& $request->get('get');
    $cookie =& $request->get('cookie');
    $files =& $request->get('files');
    $server =& $request->get('get');


    Can any one recommend which is the best method to use?

  2. #2
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is somewhat minimalistic but working API I use

    PHP Code:
    class Request {
        
    string param($name)  # return GET or POST param by name
        
    int parami($name)    # return param, converted to integer
        
    string cookie($name# return cookie
        
    string env($name)    # $_SERVER or $_ENV
        
    FILE file($name)     # $_FILES[$name]
        
    void map($func)      # apply $func to all request data
        
    void filter($func)   # filter data using func
        
    bool is_post()       # is POST request?
        
    bool is_https()      # is HTTPS request?
        
        # public properties:
        
        
    array $params$cookies$env$files


  3. #3
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The problem is when using a request wrapper it doesnt look right when a variable is an array

    example:

    $name = $_POST['name'][$language_id];

    becomes:

    $array = $request->get('name');

    $name = $array[$language_id];

  4. #4
    SitePoint Wizard dreamscape's Avatar
    Join Date
    Aug 2005
    Posts
    1,080
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is my preferred Request interface:
    PHP Code:
    <?php

    $request 
    = new Request();

    // $request->{type}
    // returns an instance of {Type}Request
    $request->get;
    $request->post;
    $request->cookie;
    $request->files;
    $request->server;
    $request->env;
    $request->argv;


    // $request->{type}->{param}
    $request->get->paramName;
    $request->post->paramName;
    $request->post->name[$language_id];


    // Sanitizing request
    // $request->{type}->sanitize->{param}
    // $request->{type}->sanitize->options->{param}
    $request->post->sanitize->paramName;
    $request->post->sanitize->asInt->paramName;
    <.smarter.web.development.>
    PHP Stuff: Plexus | Chocolate (BDD Framework... coming soon)
    Graphite

  5. #5
    SitePoint Evangelist
    Join Date
    Mar 2006
    Location
    Sweden
    Posts
    451
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    dreamscape:
    That looks really great, would you mind sharing the code for that?

  6. #6
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by blueyon View Post
    The problem is when using a request wrapper it doesnt look right when a variable is an array

    example:

    $name = $_POST['name'][$language_id];

    becomes:

    $array = $request->get('name');

    $name = $array[$language_id];
    And where's the problem? The "name" parameter is expected to be array, and $request->get('name') returns an array. Is this considered wrong?

  7. #7
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog View Post
    And where's the problem? The "name" parameter is expected to be array, and $request->get('name') returns an array. Is this considered wrong?
    What about if you wanted to get all the post data?

    $model->updateCountry($_GET['country_id'], $_POST);

  8. #8
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog View Post
    This is somewhat minimalistic but working API I use

    PHP Code:
    class Request {
        
    string param($name)  # return GET or POST param by name
        
    int parami($name)    # return param, converted to integer
        
    string cookie($name# return cookie
        
    string env($name)    # $_SERVER or $_ENV
        
    FILE file($name)     # $_FILES[$name]
        
    void map($func)      # apply $func to all request data
        
    void filter($func)   # filter data using func
        
    bool is_post()       # is POST request?
        
    bool is_https()      # is HTTPS request?
        
        # public properties:
        
        
    array $params$cookies$env$files

    I have been doing some testing and I think the way you have done this is quite good. I plan to use a simular class.

    I was getting confused by using $_REQUEST with the main get and set methods. Merging $_GET and $POST prevent problems with cookies getting in the way.

  9. #9
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    how about this?

    PHP Code:
    $request->get('post');
    $request->get('post.name');
    $request->get('get.product_id');
    $request->get('server.HTTP_HOST');

    etc.. 

  10. #10
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, practically this looks like you're programming your own language to overcome the limitations of php syntax. Doesn't make much sense to me.

  11. #11
    SitePoint Zealot Serberus's Avatar
    Join Date
    Oct 2005
    Location
    Herts, UK
    Posts
    113
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by blueyon View Post
    how about this?

    PHP Code:
    $request->get('post');
    $request->get('post.name');
    $request->get('get.product_id');
    $request->get('server.HTTP_HOST');

    etc.. 
    I actually ended up with a class that does this but I wrote it as a wrapper for sessions. I can post the source when I get back from work if you want.

  12. #12
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    $request -> get'post' ) -> get'name' ); // etc... 

  13. #13
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston View Post
    PHP Code:
    $request -> get'post' ) -> get'name' ); // etc... 
    Or:

    PHP Code:
    $request->post->name// etc... 
    Or, how about:
    PHP Code:
    $request->post['name']; // etc... 
    You can even combine the two, using an ArrayObject.

  14. #14
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, now things are just getting silly...

    But I agree; There is half a dozen ways you can do it, so the choice is basically what your most happy with I suppose. Using a delimiter however to determine the variable(s) isn't helpful.

  15. #15
    SitePoint Evangelist
    Join Date
    Apr 2003
    Location
    North Carolina, USA
    Posts
    415
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is my favorite one so far:

    PHP Code:
    <?php

    $request 
    = new Request();

    // $request->{type}
    // returns an instance of {Type}Request
    $request->get;
    $request->post;
    $request->cookie;
    $request->files;
    $request->server;
    $request->env;
    $request->argv;


    // $request->{type}->{param}
    $request->get->paramName;
    $request->post->paramName;
    $request->post->name[$language_id];


    // Sanitizing request
    // $request->{type}->sanitize->{param}
    // $request->{type}->sanitize->options->{param}
    $request->post->sanitize->paramName;
    $request->post->sanitize->asInt->paramName;

  16. #16
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Caldus View Post
    This is my favorite one so far:

    PHP Code:
    (...)
    // Sanitizing request
    // $request->{type}->sanitize->{param}
    // $request->{type}->sanitize->options->{param}
    $request->post->sanitize->paramName;
    $request->post->sanitize->asInt->paramName
    So, you wouldn't ever have a parameter, named sanitize?

    Quote Originally Posted by Dr Livingston View Post
    Well, now things are just getting silly...
    That's another way of putting it ...

  17. #17
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Caldus View Post
    $request->get->paramName;
    $request->post->paramName;
    I don't think we need distinct 'get' and 'post' methods. You just call $request->param('name'), no matter which request method was used.


    Quote Originally Posted by Caldus View Post
    // Sanitizing request
    // $request->{type}->sanitize->{param}
    What's the point of 'sanitizing'? How can a request param be 'insanitary'?

  18. #18
    SitePoint Wizard dreamscape's Avatar
    Join Date
    Aug 2005
    Posts
    1,080
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    So, you wouldn't ever have a parameter, named sanitize?
    I make sure not to, and it is highly doubtful you would have a param named "sanitize" in the first place.

    Quote Originally Posted by stereofrog View Post
    I don't think we need distinct 'get' and 'post' methods. You just call $request->param('name'), no matter which request method was used.
    I completely disagree. Not distinguishing between GET and POST leaves your application more vulnerable to remote attacks, because operations that should only be carried out via POST can now be carried out via GET.

    Quote Originally Posted by stereofrog View Post
    What's the point of 'sanitizing'? How can a request param be 'insanitary'?
    All input must be assumed to be tainted. I have it set up that my default sanitizer attempts to prevent common exploits such as XSS. And other sanitizers can be added for more specific scenarios, such as sanitizing IP addresses, etc...
    <.smarter.web.development.>
    PHP Stuff: Plexus | Chocolate (BDD Framework... coming soon)
    Graphite

  19. #19
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by dreamscape View Post
    I make sure not to, and it is highly doubtful you would have a param named "sanitize" in the first place.
    And how many magic names would you like in your interface?

    Quote Originally Posted by stereofrog View Post
    I don't think we need distinct 'get' and 'post' methods. You just call $request->param('name'), no matter which request method was used.
    There's a semantic difference between a parameter passed through GET and POST. They must be treated differently.

  20. #20
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    There's a semantic difference between a parameter passed through GET and POST. They must be treated differently.
    No, there's "semantic difference" between different request methods, not the parameters themselves. The fact that param "name" is equal to "blah", doesn't change depending on param being POSTed or GOT (?). If a request method is important for your application, just check it directly, no need to mess with different parameter sets.

    PHP Code:
    function add_record() {
       if(
    $request->method() != 'POST')
           throw <
    POST expected>
       
    $model->add_record($request->param('field_1'), $request->param('field_2')...);


  21. #21
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog View Post
    No, there's "semantic difference" between different request methods, not the parameters themselves.
    Surely there is.

    Take the following URL, which defers a user, John:

    http://example.com/users?name=john

    Now, to change john's name, we POST with the parameter name=jim in the body of the request. The server side script will now have a GET param (name=john), which is used to identify the resource (It's part of the URL), and a POST param (name=jim), which is used to update the resource.

  22. #22
    SitePoint Wizard dreamscape's Avatar
    Join Date
    Aug 2005
    Posts
    1,080
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    And how many magic names would you like in your interface?
    "sanitize" is the only reserved keyword in my interface that cannot be used as a parameter name. Since there is only the one, and I find it extremely unlikely that there would ever be a case where one would need to have a parameter named "sanitize", I find the tradeoff to be acceptable.

    I find saying something isn't good to do because there is a .00001&#37; chance it might cause a conflict to be a bit like premature optimization.
    <.smarter.web.development.>
    PHP Stuff: Plexus | Chocolate (BDD Framework... coming soon)
    Graphite

  23. #23
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by dreamscape View Post
    I find saying something isn't good to do because there is a .00001% chance it might cause a conflict to be a bit like premature optimization.
    Premature optimization is the act of sacrificing architectural concerns in order to improve performance, at a too early stage in the application development. What you're suggesting, is to pollute the namespace of your hashmap, with parameters, that have special meaning. The off chance of collision may be small, but that's not the only problem. It is not clear from the code it self, what is going on -- It presumes some a priori knowledge. That's bad design in my book.

  24. #24
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post

    Now, to change john's name, we POST with the parameter name=jim in the body of the request. The server side script will now have a GET param (name=john), which is used to identify the resource (It's part of the URL), and a POST param (name=jim), which is used to update the resource.
    I'm not a fan of get-post mixtures and try to avoid them in practice. Using POST means everything you need is in the request body, no extra dependencies, no harm.

  25. #25
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog View Post
    I'm not a fan of get-post mixtures and try to avoid them in practice. Using POST means everything you need is in the request body, no extra dependencies, no harm.
    In PHP, the querystring parameters are parsed into an array, called GET. This may be a bit misleading, since the querystring is not tied to the request method; It's part of the URL, and the URL is a necessary component of all HTTP requests (GET and POST alike). For a POST type request, the URL, and therefore the querystring, is used to identify the resource on which to carry out the request.

    That said, the querystring is largely used for carrying application state, not for identifying resources. In my example before, it would be better to use the path element of the URL, to identify the resource, rather than the querystring. It may be a general rule, that using the querystring to identify resources, is bad design. I didn't investigate this, but if that is indeed true, then there will never by querystring parameters with a POST request, and then it would be redundant to distinguish between the two sources. I'd still prefer not to have them mixed up in the same bucket, since they are not interchangeable; You use them for distinctly different types of information.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •