SitePoint Sponsor

User Tag List

Page 2 of 2 FirstFirst 12
Results 26 to 36 of 36
  1. #26
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    You would need access to the Model-domain in order to do any real validation, wouldn't you ? I honestly think that belongs to the Controller, or even the Model-layer.
    Presentation-layer objects can make calls to the domain if they need to. Some validation decisions are purely in the presentation layer though. If an http request should have two GET vars, and it only has one, the request has bad syntax - that's presentational. Later, you might call on the domain to check if a particular value is OK. A request object, at least as I use them, would have a "hasValidSyntax" method - the very first thing checked by the application controller.

    Really I see a further sub-layer in the controller - the request model - solely dedicated to receiving input, applying any filtering such as fixing magic quotes or decoding, and applying validation rules (wherever they may be defined). I'd hide the session mechanism in here as well on the grounds that this is request state. What's left after that, in the controller layer, is application controller logic.

    So the request object acts as a kind of gateway. The rest of the app gets safe, validated values from named getters as well as information about request state - such as hasValidSyntax. It completely encapsulates the input type and can be swapped out simply if you change from http to CLI. It's a kind of Cartesian boundary between external input and internal application.

  2. #27
    SitePoint Zealot
    Join Date
    Oct 2004
    Location
    naperville
    Posts
    189
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Where, do you think, is the best place to do filtering? Should this be done in the page (application?) controler?

  3. #28
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Super Phil
    Where, do you think, is the best place to do filtering? Should this be done in the page (application?) controler?
    I think it is best done later when you know exactly what you want to filter.
    Christopher

  4. #29
    SitePoint Member
    Join Date
    Jun 2005
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hello,

    This is very interesting to read -- I skimmed the "skeleton" thread and might have miss some of what motivated this distinct thread, so forgive me if so.

    I'm understanding this thread to address two questions: 1. What is the value of encapsulating incoming requests, and 2. Where does this encapsulation belong in a framework. I want to comment about the first issue.

    To sketch the needs of the CMS-type application I maintain: Some kinds of requests to the app are straightforward GET requests: "Give me this content." Others are GET requests which are much more like 'state-setters' (an ignorant term) "Give me a page which lets me edit a chunk of content." Then there are standard POST-type ('world-changers') requests: "Update something."

    In this conversation, I'm going to ignore the very straightforward GET-type requests, since they are probably better handled in other ways. Also, let me say that I haven't explored maintaining application state through SESSION, since I encountered a deployed application which was poisionous to maintain because of its session implementation -- but I bet there are good ways to use it also.

    In short, I'm throwing state information around using requests.

    The thinking which led me to write a single request gateway is this: the 'state-setters' always persisted into the 'world-changers'. I didn't want to hard-code this stuff into forms as HTML, or embed GET-requests directly. I needed an object that can form requests that establish or maintain application state without hard-coding that stuff as HTML.

    Also, given the appropriate paranoia which must be applied to user input, I didn't want to do low-level type checking all over the application. ($_GET['pageType'] must be an integer -- is it an integer? that sort of type checking).

    So, my request object has these responsibilities:

    - Create request strings. These can be GET or POST requests.
    - Examine incoming requests and perform basic type validation.
    - Provide access to request data.

    OK, so already you can see that there is something wrong, from a pure OO-style approach: "create requests strings" should be its own object. Yes. I'll assign my refactoring monkey ASAP -- until then, I live in the house I built. Please ignore that issue for now.

    What I think might be relevant to this thread is the method of creating / processing requests. If I want to get a request string:

    Code:
    $requests =& Requests::get_instance();
    $aGetRequest = $requests->formRequestString('get',
      array(
        'aRequestVar' => array(
          'type' => 'int',
          'value' => 123,
        ),  ... 
      ),
    );
    (Request object is implemented as singleton)

    As I implemented it, the request object embeds some type checking information into the name of the request (here, creating a request key named "i_aRequestString", to indicate that it damn well better be an integer). That embedded information is type-checked upon retrieval for validity.

    This has worked well for dates -- date types ("d_aDate") are turned into PEAR Date objects, which leads to a nice programming environment for dates (for a change) -- the instantiation of those objects is centralized (Extract Factory?) and I never need to parse strings for dates.

    What is best from the 'state-setter' and 'world-changer' point of view is this: I can ask the Request object to preserve incoming application state. (Again, perhaps session is better for this?) Nevermore do I need to keep track of that throughout disparate modules and dispatchers. I can also flush the existing application state.

    This was useful for writing an app which had lots of widgets ("Edit this object", "Delete this object") -- the whole mess of implementing a controller for each widget became cleaner after implementing a centralized request generator.

    So (punchline!) a centralized request object gave me a consistent way to maintain application state over GET/POST requests and handle low-level input validation.

    I hope I haven't missed the point of the thread by a yarn.

  5. #30
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Super Phil
    McGruff - you talk about the CLI a lot, and I know you've done testing with it, but I've never actually came onto an occasiaon where I had to use it. What kind of scripts are you using CLI with, if you dont mind me asking?
    Sorry I meant to reply to this earlier. I don't run a lot of stuff from the command line - network maintenance stuff like backup jobs maybe. Some scripts would transfer some, like a forum, wouldn't make much sense. Really I'm using this as an example to illustrate layering. It's a question to ask of the design. If the app is well-layered, it should be fairly straightforward to swap out one presentation layer for another.

  6. #31
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Super Phil
    Where, do you think, is the best place to do filtering? Should this be done in the page (application?) controler?
    If it's input filtering, I'd do that in the controller layer.

  7. #32
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    beprime - a singleton might not be the best way to implement a request object. See Marcus Baker's Registry article on phpPatterns. http://www.phppatterns.com/index.php...leview/75/1/1/. You can probably just pass it around where it's needed - if not maybe try a Registry.

    If you specify validation rules in key-names, you'll run into trouble. The key name is a bit overloaded ie it's got too many jobs to do, and specifying multiple rules would be very awkward.

    a centralized request object gave me a consistent way to maintain application state over GET/POST requests and handle low-level input validation
    Indeed. A request object could have methods:
    +persistFoo()
    +forgetFoo()

    I usually prefer named methods but that could just as easily be a more generic "persist" & "forget".

  8. #33
    SitePoint Member
    Join Date
    Jun 2005
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff
    If you specify validation rules in key-names, you'll run into trouble.
    McGruff, not only true, but proven in this case -- embedding validation rules in the key names can not go farther.

    When you wrote that a request-handling layer should be responsible "applying validation rules (wherever they may be defined)", where do you think they could be defined?

    To give a concrete example, suppose that there is an incoming request, as follows:

    'name' => 'richard simmons'
    'fame' => 7
    'game' => 'NOT_LAME'

    The rules to be followed are:
    - All must be safe for DB insert.
    - 'name' cannot contain non-numeric characters other than spaces
    - 'fame' is an integer which cannot exceed 10
    - 'game' refers to some kind of internal state-setting value, meaning that its value must be one of a known list of values: set = {NOT_DAME, NOT_GAME, NOT_MAME}, for example.

    Two questions:

    1. Where does the validation for these occur? (I'd think that it happens multiple places, in a sense -- the DB layer should be responsible for making sure that input is safe (or reject it); but other responsibilies might lie elsewhere)

    2. Much more interesting: where do the rules for the validation live? How do we know, given 'game', that it must correspond to an integer with 1 <= n <= 10? Does this imply that the validation should only occur at the layer/object which uses it? Doesn't that seem ... 'lame'?

  9. #34
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The rules which you've mentioned above are all to do with request syntax and so I'd see these as part of what I've been calling a request model.

    A request object would deploy validation code which checks that name, fame & game keys - and no other - are present in $_GET, and then verifies values as you have described. If the http request has valid syntax, it's possible to begin processing the request.

    Domain rules could be accessed by a request object. Sometimes they might be better left until later.

    Suppose you had a user registration but the name supplied has already been taken. As long as the name is alphanumeric, it's valid in terms of request syntax. However, when you get to the domain you discover that the new name is actually "invalid" in the sense that it's already in use and can't be re-assigned. You'd almost certainly want to wait until the domain stage to deal with that rather than try to head it off at the pass in a request object. This is more application controller logic rather than request model.

    I'm still trying to figure out my own strategy here. I keep coming back to the idea that validation is a two-stage process though. First a basic syntax check, and further checks later on in the script.

  10. #35
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I keep coming back to the idea that validation is a two-stage process though. First a basic syntax check, and further checks later on in the script.
    I have found this to be the most practical way as well.
    Christopher

  11. #36
    Massimiliano Bruno Giordano sid egg's Avatar
    Join Date
    Aug 2004
    Location
    Canada
    Posts
    1,280
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I prefer a getInt, getString, etc, which validates based on Regex's and grabs from $_REQUEST.... but, to each his own.
    GamesLib.com - the slickest, most complete and
    easily navigatible flash games site on the web.


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
  •