by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    bobate
    @bobate
    @kvnb
    I just noticed that 2 escape characters in my regexp disappeared when I entered the text above: before the hyphen and before the period. I tried to edit them back in but they disappeared again. Hmm!
    kvnb
    @kvnb

    I have to say it’s super having a personal tutor. I really appreciate the time you’re giving me.

    You're welcome. I'll do my best to help where I can but I'm still learning myself.

    So I think you’re suggesting that I validate user’s entry by setting $username = filter_var($username,… then reject the entry if the value is false, or insert it in database if it retains its value? Is that right?

    Yep. Good summary.

    I’m having some trouble making that work with a practice form on my localhost.

    What's not working, and what's the code? If you're happy to share snippets it'll be easier to figure out what's going on.

    Does that look right to you? Works on the regexr but not my practice page. Allows other chars, like double quote.?

    Regexp testers may not use the same underlying algorithm as PHP. Use your actual environment to test. In this case, [\w] is matching the double quote character, though PHP does not document this.

    I still don’t know how you entered any joke id at all since it’s auto-increment and there’s no field for it (except hidden). If it’s thru dev tools, I haven’t really figured that out yet

    Hidden fields are better thought of as 'not visible in the browser'. Dev tools can see them (use the DOM inspector) and you can still edit them. <input type='hidden' name='id' value='1'> can be changed to whatever you want and then submitted.

    Your auto-increment does not seem to be failsafe. I think you have code that mixes creating new jokes with editing existing jokes. I'd need to see the code to be more specific. Are you in control of each sql statement or are you using something like an ORM?

    Another concern is that you do not seem to be using IDs as they are submitted. If I go to http://www.ltvinfo.com/joke/edit?id=2 I can edit the joke with ID of 2 as expected. If I go to http://www.ltvinfo.com/joke/edit?id=2b I still see an edit page for the joke with ID of 2 as opposed to a 404 or other default view. SQL would not match like this.

    I suppose I must still have to validate the id before inserting the joke in the database, is that right? How do I do that if the id isn’t set until it gets to SQL? How do I stop you from setting an id?

    The simplest method is to only use a user-submitted ID to retrieve a record from the database. Validation can be done by the presence or absence of a record with that ID.

    bobate
    @bobate
    @kvnb
    Sent you a private chat
    Nate
    bobate
    @bobate

    @kvnb

    Sorry for the slow reply

    Forgiven. Lol

    (me) -g- flag. only useful with preg_match?
    That flag exists to allow you to find multiple matches in a string and return each match as a separate array entry. It is useful when you want to extract information from a string that fits a pattern, but is not useful for validation. PHP doesn't use this flag, but other languages do. Use preg_match_all instead of the flag if you need that behaviour. For validation you do not.

    Great lesson. Thanks

    if ($username == filter_var($username …
    You need to use ===. I think a blank username would get through your filters as they stand.

    Thanks, tested this and I see you’re right.

    (me) I got all of that except the submit part. How do you submit it?
    Once I've edited in the DOM inspector I can hit the Submit button on the form same as anyone would.

    Ok!, this finally worked for me. I was certain I tried before and it didn’t post, so I was perplexed. Maybe it was on my dummy form which doesn’t actually submit.
    So now I’m working on how to prevent user submitting altered hidden field. Research (SO) seems to indicate no easy way. I’m testing some ideas, like testing if user’s id matches author of joke with GET id. How do you do it?

    It's risky using code that you don't understand as you can't always tell what it will do.

    I’m kinda happy to say I think I understand each piece of php code pretty well. But I just “learned” OOP from this project, so it’s mostly the strategy of structure and why certain methods go into which classes. Jumping from class to class to method to class, trying to follow trail just to perform a single INSERT is what’s hard for me. So different from procedural (tho I think I see the benefit). And then trying to track down errors in that path. And the OOP: implements, interface, use, autoload, references(&$), dependencies, routes, \stdClass, constructorArgs, \ReflectionClass, and keeping all that in my head. I’m in awe of Tom for having written the book (~700pgs) and built the code in it. That’s genius to me. But his explanations of strategy are often over my head or difficult to keep inside it. It’s kind of like learning a spoken language, waiting for the light bulb to come on. If you can recommend some good, clear books/websites to explain strategy/structure, like where you learned it, that would help tons. I’m always searching.

    It's a little bit of a guess, but from the code you've posted I think the problematic bit is:
    private function insert($fields) {
    How is the $fields variable constructed? If I submit a non-existent ID will there be an ID field in that array?

    The insert($fields) method is part of Tom’s “Ninja framework” in the DatabaseTable class so that it can work in any database application regardless of the number or type of fields in a record. It’s called directly from save($record) method in same class, and the $fields array is POSTed from the forms for jokes, authors and categories, eg $joke = $_POST['joke'];. The forms create arrays, eg name="joke[joketext]". Possible paths are thru addJoke($joke) in Author entity, addCategory($jokeCat) in Joke entity, POSTed from form to saveEdit($category) in Category controller, or POSTed to savePermissions($author) in Register controller.
    Thanks
    Nate

    kvnb
    @kvnb
    So now I’m working on how to prevent user submitting altered hidden field.
    Don't. Users can throw anything at your server they want. Best to accept that and design your application to cope.
    kvnb
    @kvnb

    I’m kinda happy to say I think I understand each piece of php code pretty well.

    Good. I've had a look at the DatabaseTable class and it is the cause of the ID mishap. I'll talk you through it and see if that helps.

        public function save($record) {
            $entity = new $this->className(...$this->constructorArgs);
            try {
                ...
                $insertId = $this->insert($record);
                ...
            }
            catch (\PDOException $e) {
                $this->update($record);
            }
            ...
    }

    This function seems to be trying to INSERT whatever you give it and then UPDATE the record if the query throws an exception (like it would if the record already existed). So when a dud ID is put in it happily INSERTs it. The auto-increment will only work if no ID is specified on the INSERT.

    So, if I edit the ID field, the $_POST['joke[id]'] parameter will have a value, that you pass on to the $fields array, that you put into this function, that tries to INSERT it, which succeeds as INSERT will accept a value for ID, which means you have a record with whatever I put in that fits with SQL's schema for that column (probably an INT).

    kvnb
    @kvnb

    If you can recommend some good, clear books/websites to explain strategy/structure, like where you learned it, that would help tons. I’m always searching.

    To be honest, there's a lot of bad information out there on PHP. I learnt to program in Java which is designed around OOP. That helped. With PHP I mainly learnt by building things. Robert Martin's "Clean Code" book and Martin Fowler's "Patterns of Enterprise Application Architecture" were really helpful and I still refer to those. People like Tom Butler are great to refer to for being very disciplined about how they design applications using OOP, and python helped me to understand the notion of using immutable objects to help with this. I'm still trying to improve my architectural decisions.

    bobate
    @bobate
    @kvnb
    I haven’t been able to get to work on this during holidays. Just getting back to it now, with a quick question.
    I’ve seen a ton of posts about Laravel on places like Reddit, wondering if it’s something I should try. Or should I stick with raw code, thereby learning it better? I don’t need another “language” (learning curve) to try to surmount in the midst of all this. Do you use Laravel or some other framework/library?
    kvnb
    @kvnb

    Do you use Laravel or some other framework/library?

    Sometimes. I've not used Laravel, but I haven't built large projects before from scratch so it would be overkill for me. I'm starting a larger project now in my free time that I want to build using a MVC paradigm broadly in line with Tom Butler's writing (which is why I'm here). Those frameworks would be tricky to adapt to that ideology.

    I must stress that I'm a hobbyist - I program in my free time to make things I find useful to me.

    should I stick with raw code, thereby learning it better?

    I think it depends on what you are trying to do. If you're trying to learn MVC architecture then there's no point using Laravel as they've made all those decisions for you. You'd just be learning how to use Laravel. If you want a framework to help you learn OOP it might be easier to use a smaller framework that you'll find easier to understand. Frameworks are just tools - it's best to know what you want to achieve before picking which tool to use.

    bobate
    @bobate
    Thanks for that guidance. I think I'm going to explore laravel to see what I can achieve. Then hopefully I can learn better by trying to dig into the code.
    Jackiin
    @Jackiin
    Hi, guys, I am implementing a MVC architecture on my PHP project. I have a question about the View. When you have few HTML to output, it is acceptable to return the HTML in a output() method, however, what about that the page contains a lots of content?
    Jackiin
    @Jackiin
    public function output() {
        $html = '<form action="?action=authen" method="post">'
        . '<input name="username" type="text" /><br>'
        . '<input name="password" type="password" /><br>'
        . '<input value="Submit" type="submit" />';
        return $html;
    }
    
    public function alert($msg) {
        echo "<script>alert('$msg');</script>";
    }
    
    public function redirect($url) {
        header("Location: $url", true);
    }
    Tom Butler
    @TRPB
    Hi Jackiin, sorry for the late reply. You're better off using a template engine. In my articles I wanted to keep as bare-bones as possible but in a real-world project you'll probably want a template engine to do it. I'll use this opportunity to shamelessly plug Transphporm https://github.com/Level-2/Transphporm but you can also use Blade/Twig or any of the many other template engines out there.
    bulentgulsn
    @bulentgulsn
    https://github.com/TRPB/mvc-demo-refactor?files=1 how to implement dynamic header, footer, sidebar to this structure. how to update all models same request. Thank you.
    Tom Butler
    @TRPB

    After what seems like a very long time in development, I am pleased to announce I am launching a new website:

    https://insphpect.com/

    As part of my Ph.D research I'm developing a a metric for grading source code flexibility by identifying known bad practices (For example, global variables and singletons).

    To test this metric, I've developed a tool which scans source code (Currently PHP) for bad practices which are known to make the code inflexible. It grades the code and highlights areas where flexibility can be improved.

    Insphpect is currently in the testing phase so don't expect it to be perfect, but it's good enough to start to get some feedback!

    If you're a PHP programmer who writes OOP code upload your code and complete the survey to tell me what you think! You can either provide a git repo url or upload a zip file.

    Alternatively, if you're not a PHP programmer but do OOP in another language, take a look at the sample reports and complete the survey based on the recommendations given. You can also let me know if you'd like to see something similar for other languages.

    Completing the survey is very beneficial to my research but if you have any informal suggestions I'm happy to take them on here.

    Andreas Carl Wägner
    @ckrudelux
    Hello Tom, notice that you updated your article about mvc
    Hate return about now
    Nice article anyway. I'm wondering what is allowed to do in the view. My idea of it was to only provide properties. But in your example you use some methods to get the value. Does it matter?
    Tom Butler
    @TRPB
    in my example the view only provides one method, to get the final output. Do you mean the model?
    Andreas Carl Wägner
    @ckrudelux
    Sorry, I mean how much should the view know about the model. Is it just method calls without args or how much responsibility should the view have over the model?
    Tom Butler
    @TRPB
    The view will be loosely coupled to the model, so it knows what methods are available on it
    Andreas Carl Wägner
    @ckrudelux
    Okay, thanks :)
    Andreas Carl Wägner
    @ckrudelux

    Example 1:

        $user = $user->load(1);
        $user->disable($user);
        $user->save($user);

    Example 2:

        $user = $user->load(1)->disable()->save();
        $user = $user->load(2)->password('test')->save();

    Example 3:

        $loaded = $user->load(1)->getUser();
        $loaded['disabled'] = 0;
        $user->save($loaded);

    Questions that comes up from reading "Immutable MVC in PHP (Part 2) - Immutable CRUD application"

    Example 2 is what seams like its the way to go but how do I manage user creation in that case. Make the load method take an array so methods like disable and password can work their magic like password hashing. Another way would be if I let the Save method take the array methods like password and disable won't have the ability to set anything before the new user is created. Or should I pass a new user array into the construct at startup?

    sherip95
    @sherip95

    class Request {

    public function __construct($uri, $params) {
    $this->uri = $uri;
    $this->params = $params;
    }

    public function getUri() {
    return $this->uri;
    }

    public function setParam($key, $value) {
    $this->params[$key] = $value;
    return $this;
    }

    public function getParam($key) {
    if (!isset($this->params[$key])) {
    throw new \InvalidArgumentException("The request parameter with key '$key' is invalid.");
    }
    return $this->params[$key];
    }

    public function getParams() {
    return $this->params;
    }
    }

    Hi friends . Who will make me a little php router???
    something like this. like on the link
    but there are many mistakes. remove all errors. make an example. send me please
    sherip95
    @sherip95

    open this site.
    copy the code.
    correct all errors.
    add controller view model.

    and send me please

    kvnb
    @kvnb
    I tried to find out more via PM to understand what this request was about and to see if I could help. I still don't understand what you need or why and you have been rude and entitled throughout.
    can you help me?

    I want to see a finished example

    small site skeleton

    Andreas Carl Wägner
    @ckrudelux

    I was wondering, cause everything makes sense as long as its a single responsibility. Like a page for a report or a user profile or whatever you can come up with. But when you come to a home page witch can be a bit of everything like an overview.

    The question is:

    • Do I repeat the functionality of other models in the model?
    • Do I use models in a model?
      • And do I call the models, model in that case?
    -- Model --
    class Home {
    
        public $welcomeMessage;
        public $houses;
        public $cars;
        public $blog;
    
    }
    
    -- View --
    <h1>Store</h1>
    <p><?php Home->welcomeMessage; ?></p>
    <h2>Cars I own</h2>
    <table>
        <?php foreach(Home->cars->owned as $car):
        <tr>
            <td>$car...</td>
        </tr>
        <?php endforeach;?>
    </table>
    
    <h2>Houses For Sale</h2>
    <table>
        <?php foreach(Home->houses->sale as $house):
        <tr>
            <td>$house...</td>
        </tr>
        <?php endforeach;?>
    </table>
    koalape
    @koalape
    @TRPB I noticed that you hosted a MBP Arch build .iso with the installed drivers here: https://r.je/tmp/arch-mbp.iso, but now the image has been taken down. Do you have another link for the image? I am not in a good position right now to make my own build and I do not have a lined keyboard or mouse.
    Karl Austin
    @KarlAustin_gitlab
    HI all. Looking for some advice. I've inherited a code base that I need to continue to develop. It's basically a modelling of a service that uses a REST API, can be thought of as: Service has Companies, Companies have Users and Applications. So there are methods like service->getCompanies(), company->getUsers() etc. which returns a collection of Company/User objects. This presents an issue for any DI (and also testing). Any suggestions on how I can "solve" this?
    Karl Austin
    @KarlAustin_gitlab
    Other than for testing, I'm not concerned about the tight coupling between Company & Users or Company & Application - because they're already tightly coupled to the underlying API.
    Andreas Carl Wägner
    @ckrudelux
    Pass the DI to the constructor or pass objects required to the constructor. If you pass the DI to the constructor passing classname could be a good idea
    Karl Austin
    @KarlAustin_gitlab
    That was my thought, although was trying to avoid passing the DI around, e.g. courier
    Andreas Carl Wägner
    @ckrudelux
    If you don't want to pass the DI around you have to change the classes so that all dependecies loads through the constructor
    Tom Butler
    @TRPB

    It's probably not a difficult refactor, replace new Foo() with $foo and pass in the instance as a constructor argument. You'll also need to change anywhere the top level class is instantiated to supply the constructor arguments.... or instantiate it with the DIC.

    ( insphpect.com can actually somewhat do this automatically and generate a patch, it's a bit buggy at the moment and needs tweaking... when I have time I'll release the code)

    Karl Austin
    @KarlAustin_gitlab
    Thanks. Currently refactoring it, biiiig change.
    Karl Austin
    @KarlAustin_gitlab
    Run in to a road block, I seem to have broken things when trying to pass in an already instantiated object (can't be helped, not my app, my code it just a module for it).
    Karl Austin
    @KarlAustin_gitlab
    Using Dice::INSTANCE, with either the object (one error), or with a closure. With closure it still tries to create a new instance, even though I can see it has done the sub
    Karl Austin
    @KarlAustin_gitlab
    Managed to make it work by passing as a constructParam instead, but not ideal
    Karl Austin
    @KarlAustin_gitlab
    Also, before I forget, thanks for making a great bit of kit with Dice :)
    Matthias
    @MatthiasSaihttam
    @TRPB It looks like that sharepoint/onedrive link has broken as well, if you weren't aware.
    Matthias
    @MatthiasSaihttam
    It looks https://github.com/JPyke3/arch-mbp-archiso/releases has the same ISO (I can), so pointing people at that might be a viable option.