patricklouys / no-framework-tutorial Goto Github PK
View Code? Open in Web Editor NEWA small tutorial to show how to create a PHP application without a framework.
License: MIT License
A small tutorial to show how to create a PHP application without a framework.
License: MIT License
Hello!
First of all, thank you very much for this tutorial, it's great!
I'm stuck at Part 10, I've added the router for the slug
['GET', '/{slug}', ['Example\Controllers\Page', 'show']]
and I've added the var_dump($params);
on the Page.php file.
But when I try to access http://localhost:8000/test but every time I get the Not Found apache error.
What should I do?
Thank you!
Hi Patrick,
I enjoyed your tutorial very much and was looking forward to find out more. Seems like you stopped working on it, right? We have Autumn/Winter 2017 now and the last words were from "cold days 2016".
I know there are more important things in life but I'd like to know if sth will ever be continued.
I was checking this part from the gitpage from patrick: github.com/PatrickLouys/no-framework-tutorial/blob/master/โฆ
But my composer won't run: "php": ">=5.5.0"
that part
paste.jesse-obrien.ca/Uqn
Thank you for the tutorial Patrick,
Working through part: 11-page-menu of the tutorial Twig throws an exception (see below), I'm sure I did everything right; IMHO 'as a student of PHP' this is a result of changes long after you published this and an update to the content might be required. I'll let you be the judge of that.
LogicException: You must set a loader first.
at Line 819 in /var/www/vendor/twig/twig/src/Environment.php
My composer.json uses
"twig/twig": "~1.0"
which installed version "1.42-dev"
I found twigphp/Twig#2907 that helped me to get it working by:
Changing Dependencies.php for Twig
from
$injector->delegate('Twig_Environment', function () use ($injector) {
to
$injector->delegate('\Twig\Environment', function () use ($injector) {
and changing the constructor in TwigRenderer.php
from
public function __construct(Twig_Environment $renderer)
to
public function __construct(\Twig\Environment $renderer)
Thanks again for the great tutorial!
You've missed out the need to use an .htaccess
file for Apache users for the Front Controller pattern. The one which works for me is:
RewriteEngine On
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
First of all, let me say I really like Auryn since you made me discover it.
But, I've been learning these past months about DI and containers and all that stuff, and I don't really think that other DI containers fall in the service locator antipattern, as pointed out here.
So, as far as I understand, getting the constructor arguments from the container is not a bad practice. The antipattern would be passing the container as a constructor argument, and using it inside the class.
Am I mistaken, or there is something I still don't understand?
Thanks
I am trying to go through 10-dynamic-pages but can't seem to get the InvalidPageException to work. properly. When going to the localhost:8000/public it seems to show me the page properly like so
but when going to a certain page that doesn't exist in my project like localhost:8000/pages/page-six.md it seems to not be showing the InvalidPageException
I have updated my code on github/lowheartrate/heartfx with my project if you need to look it over for anything wrong with the code but can't seem to figure out why its not showing the InvalidPageException myself ๐
Add a notice to each chapter that this is not the code in it's final form.
Running current code for Router section results in following error:
Cannot modify header information - headers already sent
It is caused by echo
statements in route resolvers and can be fixed if resolvers return content instead.
As it is, one cannot finish this section without an exception page. Is this behavior intentional?
"Education is the key here. You want to show your readers the whys of how a framework operates. Demonstrate areas of responsibility - accepting input, figuring out how to handle the request, validating input in the context of the request, handling the request, operating request-specific business logic, gathering of data as a result of the logic, then presenting the data to the user." - Charles
I have been stuck on this one for a while. I cannot for the life of me figure out how to do this I am at the step where you would switch the renderer alias from Mustache_Engine to Twig. here is my code
/**
* Mustache Renderer
*/
/*$injector->alias('Todo\Template\Renderer', 'Todo\Template\MustacheRenderer');
$injector->define('Mustache_Engine', [
':options' => [
'loader' => new Mustache_Loader_FilesystemLoader(dirname(__DIR__) . '/templates', [
'extension' => '.html',
]),
],
]);*/
/**
* Twig Environment
*/
$injector->alias('Todo\Template\Renderer', 'Todo\Template\TwigRenderer');
$injector->delegate('Twig_Environment', function () use ($injector) {
$loader = new Twig_Loader_Filesystem(dirname(__DIR__) . '/templates');
return new Twig_Environment($loader);
});
But All I get is the following error
LogicException
You must set a loader first.
Noticed your domain artofphp.com is going nowhere and showing a blank page. Wondered how progress is going with your book? Sounds like a very interesting premise!
revisit the "routing" and "dynamic pages" chapters and then do a chapter on DB handling
Hi there!
First, there is no new issue here, more like request for improving this guide!
Now, I respect all contributors here and I would like to extend/use this guide with illuminate/database. Since I need some help here with this, how to properly glue it to existing code?
Thanks
Hi,
Thanks for the tutorial. It is very helpful.
I've been trying to add more feeature like config, validation, log, repositories etc. and want to inject them to controllers via interfaces.
I created an abstract base controller and concrete controllers by extending it. But constructor parameters are growing. If I extend the base class and want to add more dependencies, I would need get same parameters again and call parent::__constructor
. Is it reasonable? Is there a better way?
Best Regards
Hi!
I am followin this tutorial but have problem startin with part 05&06.
Aftre applying changes decribed in 05 part into ./src/Bootstrap.php I always get 404 message, so I am quite confused how exactly should ./src/Bootstrap.php look like.
Can you please make this chapter 05 and 06 more clear?
Thanks!
Thanks for the great information. It seems PHP has matured a bit! I've been following your tutorial and implemented the parts I felt I needed. I also mocked a database and I wanted to share that info. I'm open to criticism.
In bootstrap.php:
//$db = $injector->make('\Main\Database'); //uncomment to use RDBMS
$db = $injector->make('\Mock\Database');
In my controller:
use \Main\Database; //uncomment to use RDBMS
use \Mock\Database;
I then pass the $db object to my routes and $controllers. Done!
Here is the mock class as well:
namespace Mock;
class Database {
private $dbname;
private $dbhost;
private $user;
private $password;
public function __construct() {
}
public function query() {
}
public function getUsers() {
function mustachify($user) { return array('name' => $user); }
$users = [mustachify('@funkytaco'),mustachify('@PatrickLouys'),mustachify('@Rican7')];
return $users;
}
}
I'm not too sure I like the name Database
for the class, but it works for now. Also, I'm thinking it should probably be a wrapper like your Renderer class.
rename controller to presenter
Hello Patrick.
Could I translate it into Chinese?
Hi Steve how i can using database.you known about my question is that how i can view database record and which packages use for that please share me about that i fellow your tutorial every things work fine .now i m connect to database and fetch the record from database so where i use database class and how i can do that please please
Any suggestions beyond Aura.Cli for writing php scripts for command line usage?
It would be nice if you could make the code for the tutorial available at each stage of the process.
Also, are you planning to continue this?
Markdown parsing mentioned in Dynamic Pages but not implemented. Is intentional as an exercise or missing?
Because of using Whoops error handling, the InvalidPageException is never being caught. The Whoops exception handler catches it and the 404 response never appears.
When I;m done with chapter '08-dependency-injector'. I got this error.
Class 'Auryn\Provider' not found
What can I do to resolve this problem? I followed exactly the tutorial here.
Thanks
Explain how to: config file that is in .gitignore
How add route rest and redirect async data via ajax in the part of router ?
If I switched to a different templating system it might have a completely different templating syntax language. So having the change instances of the word "mustache" to something else in a few places in the code would be the smaller part of the amount of work involved in switching templating systems.
Why do you have such a strong opinion on dependency injection vs service locators with only 1 reference link, which supports your view; but have no opinion on templating systems and offer fair billing to both sides by provide 2 good links?
You should be fair and give links to both sides of the argument for DI
REMOVED SPAM
Argument 1 passed to Example\Controllers\Homepage::__construct() must be an instance of Example\Controllers\Response, instance of Http\HttpResponse given
I don't how to fix this.
Fixed by changing Homepage controller constructor to
public function __construct(\Http\HttpResponse $response)
Should I not have needed to do this?
Nevermind. I missed the USE statement in the example code.
Hi there!
In chapter 09 last proposed change in Homepage controller is
Now you can go back to your Homepage controller and change the render line to
$content = $this->renderer->render('Homepage', $data);
and next line we have reference to antoher variable
$this->response->setContent($html);
Should be:
$html =$this->renderer->render('Homepage', $data);`
$this->response->setContent($html);
Anyway great tutorial, vote for an ORM/DBAL to be explained as well.
I saw someone asked for Chinese but because of i haven't seen licence file i want to ask again. Can i translate to Turkish language? And i really suggest putting licence file or information, so if someone want to use your tutorial, he can understand what he can do with it or don't.
I'm working on the router and despite lot's of troubleshooting efforts I can't get the Dispatcher to find the route.
If I do a var_dump on $dispatcher I get the following which I think is ok:
object(FastRoute\Dispatcher\GroupCountBased)#12 (2) { ["staticRouteMap":protected]=> array(1) { ["GET"]=> array(1) { ["/"]=> array(2) { [0]=> string(32) "NOFRAMEWORK\Controllers\Homepage" [1]=> string(4) "show" } } } ["variableRouteData":protected]=> array(0) { } } array(1) { [0]=> int(0) }
I believe it has to do with this line, I'm not sure it's being passed what it's expecting.
$routeInfo = $dispatcher->dispatch($request->getMethod(), $request->getPath());
$request->getMethod() returns GET
$request->getPath() returns /public/
Do those values seem correct?
I am obviously learning here, and appreciate any help.
Thank You
Hi there,
On part 11 after creating the FrontendRenderer and the FrontendTwigRenderer, I ran the server and the error message of "Object of class Example\Template\FrontendTwigRenderer could not be converted to string" is showing. I also changed the references from Renderer to FrontendRenderer in the controllers and removed menu items from the Homepage controller. Do you know what may be happening? If you need any screenshots from my code, please let me know
Thank you for your help.
So when following a tutorial I tend to write the code over instead of copy pasting. However I got a bit confused in the naming of the variables. I suggest to rename $woops
to $whoops
for the sake of consistency.
Struggled with Part 6 for a while because it kept telling the class Example\Controllers\Homepage
could not be found. Took me about two hours to figure out I needed to run composer update
.
This is not immediately obvious and should be mentioned in the tutorial.
Hi ,
I was looking https://github.com/PatrickLouys/no-framework-tutorial/blob/master/6-dispatching-to-a-class.md and seems Aura.Dispatcher is a nice fit . Checkout in case if you have not looked https://github.com/auraphp/Aura.Dispatcher .
Thanks!
This has been bugging me:
$injector = new \Auryn\Injector;
$injector->alias('Http\Response', 'Http\HttpResponse');
$injector->share('Http\HttpRequest');
$injector->define('Http\HttpRequest', [
':get' => $_GET,
':post' => $_POST,
':cookies' => $_COOKIE,
':files' => $_FILES,
':server' => $_SERVER,
]);
$injector->alias('Http\Request', 'Http\HttpRequest');
$injector->share('Http\HttpResponse');
return $injector;
Shouldn't...
$injector->share('Http\HttpRequest');
...and
$injector->share('Http\HttpResponse');
be switched? If not, can you explain why that order? Thanks.
If the page controller needs the custom InvalidPageException to give the right kind of error message, isn't that a dependency? So should't it be added to the dependency injector settings and the constructor of the page controller instead of using new?
Step 4 should say "add the following code before the foreach loop that sends headers" (or similar) instead of
add the following code between the code snippets from above:
Hi,
It'd be pretty good to have a "Login" chapter.
A simple login form (I'm thinking that introducing assets management is a thing too, but for another issue) that lets a user login. Also, a register form. And a logout link.
A database chapter and a session chapter need to be introduced before though.
The backend of the login would simply be a table and using password_hash
/password_verify
.
After that, the backend of the login could be switched to OAuth. This way, you show the "replace implementations", through an Authenticator
interface.
Cheers,
Hi @PatrickLouys Thanks for this tutorial, I am able to create a simple web-app. But with the traffic comes from other non-english speaking user.Can you post a simple tutorial n how to integrate Twig with I8n. Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.