PHP MVC Pattern - View Parameters Exploit - Full PHP 8 Tutorial
HTML-код
- Опубликовано: 16 июл 2024
- In this lesson, you will learn what the MVC pattern is, how it works and we will implement the basic parts of the MVC pattern. We'll refactor our existing code from previous lessons to use controllers & then implement views. We'll explore how an attacker could exploit certain functions/approaches that developers may take to gain access to sensitive information like database credentials & so on.
SOME OF THE WAYS YOU CAN SUPPORT THE CHANNEL
👍 Smash the like button
🤝 Subscribe to the channel & turn the notifications on
💬 Post comments, any feedback is greatly appreciated
⭐ Become a Patreon: / programwithgio
THANK YOU!
LESSON 2.27
Course Outline - github.com/ggelashvili/learnp...
Course Playlist - • Learn PHP The Right Wa...
CHAPTERS
00:00 - What is MVC
04:30 - Implementing basic MVC (Controllers & Views)
12:31 - Layout support (exercise)
14:46 - Pass params from the controller to views using variable variables or extract function
17:26 - Potential exploit with variable variables & extract function
19:55 - Overview of Models
21:02 - Where does validation belong, in Model or Controller?
The presentation of these lessons is nothing short of amazing.
You show us how to keep refining the code until it is succinct, but not so bare bones that it no longer is easy to understand.
You show us how to interpret error messages and resolve them. The fact that you include error messages is so helpful to the learning process
You never use a function/method without first explaining what it does and the rationale for its choice. All this background information is so necessary, and you never leave it out.
The guided tour of the PHP manual is extremely welcome too. As a complete noob, having someone show how to find the information and interpret it is unbelievably helpful.
Thanks again for this course. It simply is the best!
Happy to hear this, thank you 💙💙
This PHP course is astonishing! Thanks a million!
You're very welcome, thank you 💙
This was an awesome leasson Gio! Much easier to follow after the clear visual presentation at the beginning.
That's it for this week. See you on Monday!
Thank you 🙌
This PHP course / Bootcamp is amazing
This series is a serious gem
Thank you 🙌
Gio thanks for this, the MVC pattern makes a lot of sense. It kinda seems like a lot but it's totally scalable. I'm learning.
Awesome, keep going
Thanks for making clear all the differences in diagram versions, when i tried to understand mvc earlier, seeing all these different diagrams was really confusing.
You're welcome 💙, glad it was helpful
Amazing job!
Gio you are the best, you are awesome. And thanks a lot for teaching so patiently. Wanna note that you are doing an amazing thing to give people skills and earn a better life my man. Loves from Azerbaijan!
Thank you so much
Thanks for your useful videos
I also use validations in the controllers and form requests :)
You're welcome 🙌
Excelente guía, nosotros también hicimos un tutorial sobre MVC, pero lo adecuamos al uso cotidiano para darle una aproximación mas humana.. pero este que claro de igual manera =)
Thank you
Thanks boss Gio you taught me what i did not know in php very grateful
Glad to hear that
the content is amazing, thank you very much.
Thank you 🙌
When i tried to implement MVC pattern myself sometime ago, at first i did all the validation in controllers, but it looked really ugly with all the validation logic so i moved validation to models. Adding separate layer to handle it sounds like an ideal solution. Your channel is da best btw :DD
Thank you 🙌
So thanks gio, you are so help me!
You're welcome
Thank you so much!
You're welcome 👍
Amazing job and coverage, are you also going to make a seperate lesson on layouts? Thank you for your hard work!
Thank you. No plans for that, though it may come up in a project that we'll be working on.
it is perfect.
Very professional explanation ❤
Thank you
Thank you.
💙
This should be everyone's one stop shop for anything relating to PHP. Thank you GIO.
Thank you 🙏
Thanks!
Thank you for your support 🙏💙
thank you!
You're welcome
The diagram versions was the best actually it helped me a lot to understand for what each of MVC stays for, I have used Laravel a lot and it really covers all this topic, watching the video one time gave me some problems. Thanks a lot GIO. Also please one question about autoloading, Is there any easy way for autoloading using spl_autoload_register() this function or not?
Happy to hear. Using composer is best for autoloading
@@ProgramWithGio Got ya, gonna continue that way 👍👍
Magic methods are awesome
Yes they are
Thanks
You're welcome
nice!
Thanks
thanks
You got it 💙
9:22 Gio, what drawbacks can you potentially see in simply using the file_get_contents() function to return the views' HTML instead of creating an output buffer like you did here?
You would not be able to pass down parameters
Thank you for sharing your knowledge. Maybe by chance you have plans to create reliable MVC framework which can be used in production? It is very hard to find reliable content and good practice.
Thank you. No plans to make a framework from scratch. Laravel/Symfony/Slim are great frameworks.
Hello, I would love to know differences between PHP frameworks like Laravel and Symphony, you mentioned that Laravel is more than an implementation of MVC and its way more powerful. do you recommend any resources about this topic? or make separate video explaining the differences please. btw the whole course is just marvelous. keep it up!
Cant put all the differences in the form of comment but, to put it simply, its different mindset & way of coding/structuring your apps. Laravel has a lot of things built in & is built with DX in mind, makes it a lot easier to get started & work with, while Symfony focuses on architecture & design but is not so simple to get started & work with. Both are great frameworks, I use Laravel on my day to day. As long as you know what you are doing & know how certain things work behind the scenes within the framework you should be good with either. Laracasts has great resources on Laravel & I think there is SymfonyCasts also that has content around Symfony.
Hi, Gio. On 12:08 Could you please explain to me how the method "render" is being called after you changed the return type of the function index to VIEW and is not casting the return to string anymore and therefore the magic method __tostring() is not being called anymore?
toString is still being called because under the hood it still gets cast to string implicitly
I made layout.php file (html layout), within the body I have include $viewPath. In the View class I made DEFAULT_LAYOUT constant that points to that layout.php, then in the render method between ob_start and ob_get>clean I include that DEFAULT_LAYOUT. It seems to be working for now, dont know will it cause problems later :)
That's awesome. That's the best way to learn by trying things out. Good job 👍
Hello Gio, thank you for this amazing course! Just a quick question: Isn't using ob_get_flush() better instead of ob_get_clean() in this case? According to docs, ob_get_clean() doesn't turn off output buffering. In majority of cases I think it probably doesn't matter since render is the last thing we will be returning, but there could be some problems with multiple renders maybe? Let me know what you think, thanks! :)
Hey, while they essentially do the same thing they are still different, ob_get_flush will print the content while ob_get_clean returns the content without printing. Both of them terminate the buffer.
@@ProgramWithGio Thanks! It makes more sense to me now.
Amen!
🙏🙏
is it ok to use ob_start() to include an entire html with a lot of css and javascript animation and return it as a string with ob_get_clean()?
Depends how big the file is. I would have css loaded from stylesheet and js from its own file.
I'm in a shock how simple to exploit views)
🙀. As long as $data does not include the user input you should be fine
Question. How come view/index.php has access to $this variable (stated in 15:20 ) if render() method is just returning a string copy of the include to HomeController then HomeController returning it to public/index.php (File where the Router is being used)?
Because the file is being included within that render method & the render method has access to $this variable correct? Therefore the included file also has access to the $this variable.
@@ProgramWithGioHad to re-watch it and now what confuses me is the purpose of returning ob_get_clean() if you could have just cleaned and closed the OB.
Was it just to satisfy the expected return type of the controller calling the render method?
@@jeloace ob_get_clean returns the current buffer content & then cleans it up, it essentially is a shortcut for running 2 functions. Check the documentation here: www.php.net/ob_get_clean
@@ProgramWithGioThank you
Gio your tutorials are solid! My son and I are following and everything is working but one piece. We aren't able to get the router to process curly brace vars I couldn't find the router code in your git because this lesson is missing. Where can I find that?
Thank you, happy to hear that. We did not implement route parameter support, later in the series we use Slim PHP which comes with built in router & has that support, so keep watching & you will get there. Some of these lessons are missing source code because they are meant just for learning purposes and not to be used in production, just to understand how it works basically. Later in the series we work on a project with proper implementation.
im loving this serie ... could you share this code ?
Thank you. Keep watching and you'll get to the source code eventually. Link to repo should be in description.
about the layout support, I will add {{content}} in the middle of my html, I explode it in the php file and replace {{content}} with the real content I want to display, then I display the whole layout. This assumes that my php script will get the layout from layout.php as a string, so I can use the explode function.
Is this the right approach ??
Thats a common simple approach, I would watch for the memory consumption though since you are probably using file_get_contents to load entire view file and then replace so depending on how big the view file is it can cause issues later. Also this approach would not support nested views.
VScode doesn't do auto refactor. what can be done? i have PHP Intelephense
installed PHP Namespace Resolver maybe it will help
I don't use vscode so I'm not sure. I would research in google
I want to thank you for the amazing educational content! Thank you so much!
I have a question about the following topic:
In the View class, within the make method, we are returning new static($view); :
public static function make(string $view, array $params = []): static {
return new static($view);
}
However, in the HomeController controller, we are calling the make method in the following way:
public function index() {
return View::make('home');
}
This means that an instance of the View class will always be created. However, in the make method, we are using new static for some reason. But with this usage, when calling View::make('home'), an instance of the class in which this call is made will never be created. So, why do you specifically use new static($view) instead of new self($view) or new View($view)? What are its advantages?
Its for late static binding, if you were to extend View class in another class like OtherView or something & then call OtherView::make() it would return the correct instance, if you did return new View or return new self then it would return always View object & not OtherView even if you called it from OtherView
Thank you 🙏@@ProgramWithGio
Hi Gio, thank you so much for this amazing lesson, u are amazing teacher :)
I have a question please, I decided after finishing this series i will jump into laravel but before that
what if i learn how to create MVC like laravel from scratch, this MVC will have the below
Custom Routing
- Composer
- Controllers
- Views/Layouts
- Models
- Migrations
- Form widget classes
- Processing of request data
- Validations
- Registration/Login
- Simple Active Record
- Session Flash messages
- Middlewares
- Application events
- Framework reusable/installable core
Do you think this will be a good project to put it in my CV and help me to be better PHP DEV??
Hello. Sure that can be a great project for learning purpose, it will help you understand the inner workings of frameworks like Laravel. I would advise though to take it easy & don't burn out, cause I've been there where I tried to create MVC framework from scratch and got burnt out by trying to build everything & make it usable for production. Build it just for education purpose & not with a purpose to use it in production would be my recommendation.
@@ProgramWithGio Gio, Thank u so much for replying back to me, I really appreciate that
. I found series for building mvc so i wanted to make sure this will add some value to me and my CV. i just want to work as PHP laravel very soon,
I got an interneship at a company for 3 month and 2 weeks, it was unpaid, the lead software eng in this company told me that i am good junior software dev and after the internship the company will give me an offer, and during the internship i used to ask him is there any thing i need to learn? he said no just focus on the tasks you are good, and after the internship they told me that i am not a good software dev and i need to study PHP and laravel more and more so why u did not tell my which topic i need to learn form the beginning ?, can u believe that haha, so i decided to finish this series and put the final project in my cv and MVC project as well and jump into laravel and build project like e commerce or booking and apply for job, do u think this is a good plan ??
by the way i learnt nodejs and build many RESTFUL API projects like booking, social media, food order and e commerce, but i forgot nodejs and how i built my projects coz i did not touch node js during the internship so i decided to learn php coz i liked it a lot
@@AhmedAdel-xg1cm Sorry to hear that, does not sound like a good company/team to be honest. I think you got a good plan, stick with it & take breaks when needed, don't overdo it. Also keep things simple, you don't need to implement every single design pattern
@@ProgramWithGio Gio, you are so kind thank you so much, when i get a job i will tell you :)
The world is strange, you do not know me but you answer my questions and try to help me, unlike the team in the company they know me but did not try to guide or help me, Thank you so mush you are my role model :)
@@AhmedAdel-xg1cm You're welcome. Sometimes people forget that they also started from nothing & learned their way, no one is born with master software engineering skills. Me & the team you worked in all been to the place you are now, it's just some forget that or are just lazy to offer advice & guidance. Keep your head up & be consistent with your learning and you'll do great things, I'm sure of it.
Good luck 💙
Including file between ob_start and ob_get_clean is not working, do you think the problem might be in php.ini config? ob_end_flush works instead
Do you get any errors? You can ping me on Twitter & I can help troubleshoot the issue
found any solution?!!
@@abdulrahman-ej7me Hi, sorry i don't remember how i solved this, maybe it was just matter of echoing it since ob_get_clean() returns string.
Let me know if this helped
@@ProgramWithGio I have the same problem, it shows a white page.
In HomeController have to give an echo instead of return and remove the return type, or use ob_get_flush() and change the return type to a string.
Any ideas?
@@kubenjs Check the App.php implementation, inside the run method we use echo to echo out the resolved route. Maybe thats missing from your part cause you dont need to add echo inside the controller
Can you please teach us that how to create a full MVC framework from strach. Would be very helpful. I like your teaching style...
Also please add this functionality in MVC framework like .. how to add elequent Orm And blade template engine...
I have intermediate knowledge of laravel but I want to know how actually laravel work behind the scenes.
Also sometimes I feel that laravel is to heavy framework for smaller projects... That's why I want to build custom MVC framework that has same mvc pattern like laravel and use some of laravel packages that provides orm and template engine packages for easy manipulate database and view..
I really appreciate for your kind tutorial.
I wouldn't build a framework from scratch which is why I wouldn't teach it. Small parts yes. In section 3 we also add eloquent as well as doctrine ORM and explain how you can use both.
Templating engine is a good idea, will add that to my list of videos to make for this series. Thank you
@@ProgramWithGio thanks for the reply ... Sure i would check that ORM tutorial and waiting for template engine tutorial.
Also if you know some MVC framework books that help me to gain my knowledge ... Please suggest some of books i would like to read. Thanks
@@devhenry9054 no specific books to recommend but I would just go through MVC pattern in general and read few articles about it since you will get different perspectives from different people
how I can load css files and js files in my views because I got routeNotFound exception. Folder structure is: views, css files, js files all in resources folder. .htaccess I take it from laravel framework.
css & js files would need to be in public directory, either you put it there or you need to have a build process
Sorry bro can you give a simple example when you say I need to have a build process but those files still need to be in the public directory@@ProgramWithGio
with build process you put your css/js in resources, then use a bundler or just simple npm script to bundle css/js & build/compile it into a single css/js file and place it under /public. Most front-end frameworks do this for you.
i dont understand the new static() return from the make function...is that an anoymous class? what is the reason to return an object
Check Late Static Binding, it returns a new object of the calling class, so whatever class calls the make method.
@@ProgramWithGio thanks i will check it
@@ProgramWithGio i checked it but late static binding is with inheritance? you dont use it in this example (inheritance)
@@devanii yup, in this case I'm using it in case we decide to use inheritance, otherwise self would work the same way until inheritance is used
@@ProgramWithGio but is the make method only for the "eye" ? esthetical? it only returns the view class..so you could also do return new View('index') in the index method of the home controller
Hi Gio, do you have any paid courses?
Hello. Currently I don't have any paid courses, maybe next year :)
Gio I'm sorry my brain stopped..why does the method render needs to return a string? Amazing series btw.
No worries, we return string so that we can echo the content to display it, we don't want to echo it within the render method because we don't want to display things right away
Hello, amazing videos - is possible to download source code for that MVC pattern? thank you
Thank you. Lesson 2.33 has the source code along with the challenge but the skeleton of the MVC is there in the repository. ruclips.net/video/D1EshhwNt48/видео.html
@@ProgramWithGio many thanks
I just build a project with simple MVC pattern and kinda jump to this video early bcs I wanna know more about the MVC. Now I feels demotivated like I haven't really learn anything.
I would watch earlier videos also, that might help you understand things more.
Maybe stupid question...
Class View in this code is a Model?
It's not a stupid question. View.php is not model, think of it like a core class to handle view rendering, like a base view class that is responsible for rendering view files.
@@ProgramWithGio thank you for an answer. But where is the Model in this code?
@@myyyp1 Model isn't covered yet, it's covered in separate video. If you continue with the playlist you'll get to it
@@ProgramWithGio Thank you very much. Can you tell me the title of video where model is shown?
@@myyyp1 you can find all videos listed here: github.com/ggelashvili/learnphptherightway-outline search for Model, I think it's lesson 2.32
I have been going back and forth, i decided i prefer my own framework ive built myself.
Sounds good
Is this code available to download?
In later videos there are links to GitHub repo in description
Exposing .env and other important file contents was shocked, now I need to find a way to protect it. :/
Just be sure you are not passing user input to functions like extract or use them with variable variables. If you do need user input then you need to sanitize it. In that case we had one variable viewPath so you could unset($this->params['viewPath'] right before extract and that would ensure that your viewPath variable doesnt get overwritten. That's one way, better way is to simply not pass user input directly to such functions
@@ProgramWithGio unsetting the variable is what first come to my mind, which means we are reserving that variable name, and developers can't use it.. hmm..
Found a solution imho.
was:
$file = $this->findFile($view);
require $file;
now just:
require $this->findFile($view);
@@TheArmanist Right, setting viewPath immediately before it is used, would be one option. Best to combine all forms of validation for security :)
Hi Teacher , I built upgrade functions View
public function render(bool $IsContent= false) {
$viewpath = VIEW_PATH . '/' . $this->view .'.php';
$template = file_get_contents(__DIR__.DIRECTORY_SEPARATOR.'..\View\view.html');
if ($IsContent) {
$content = file_get_contents(__DIR__.DIRECTORY_SEPARATOR."..\View\\".$this->view.".php");
$template = str_replace('{{content}}' ,$content ,$template);
return $template;
}else {
if (!file_exists($viewpath)) {
echo "VIEW : FILE CONTAIN VIEW NOT AVALBLE OR FORGOT EXTENSION";
}
ob_start();
include $viewpath;
return (string) ob_get_clean();
}
but i dont know how to add navbar for all pages (and this navbar check if user Logined or not )
if fix it : public function render(bool $WithLayouts = false)
{
$viewpath = VIEW_PATH . '/' . $this->view . '.php';
// store params into variables
foreach ($this->params as $key => $value ) {
$$key = $value ;
}
if ($WithLayouts) {
if (!file_exists($viewpath)) {
throw new \ErrorException("PAGE NOT FOUND");
}
ob_start();
//navbar
include(VIEW_PATH.'/Navbar.php');
//content
include $viewpath;
return (string) ob_get_clean();
} else {
ob_start();
//navbar
include(VIEW_PATH.'/Navbar.php');
//content
include(__DIR__ . DIRECTORY_SEPARATOR . "..\View\\" . $this->view . ".php");
$content = (string) ob_get_clean();
include(VIEW_PATH.'/template.php');
}
Awesome, glad you figured it out. Note that later in series we use Twig templating engine which supports this out of the box & has a lot more features.
@@ProgramWithGio Thank uuuuu
Don't use that, it is bad. Use file_get_contents and str_replace to avoid variable and buffer contamination.
I would disagree. File get contents loads it to a string while require evaluates the PHP file, so you would need to build a templating system with proper parsing. Also file get contents + str replace are slower given the extra steps.
Why are you teaching something that is "not to be used in production", obviously just wasting time. Why not teach something that is usable in production. I am sorry, cannot fathom that.
Because in this lesson we are covering the concept of it, later we work on a project that can be used in production. This is to understand what MVC is, how it works behind the scenes in most frameworks etc. But you cant use this in production because its missing a lot of the features that you would need that you get from a framework. Hope this answers your question.
This video is a mess e the explanation is boring, feels like a continuation, but the title does not imply that.
I'm sorry you feel that way. This is a series, its indicated in the thumbnail, its section 2, lesson 27. The description of the video contains github repo that lists all the lessons in the series. If you have specific questions feel free to ask, I'll be happy to clarify.
Thank you! (comment in support of channel)
thanks
💙