Senior software engineer on the frontend infrastructure team at Dave.
Email me for inquiries, questions, or just to say hi! ๐
The simple PHP router
License: MIT License
respected,
i am using this router! easy to understand!
but i am getting following error
preg_match(): Compilation failed: unknown property name after \P or \p at offset 3
at Macaw.php line number 96
it is on my root dir!i am using xampp on windows + my htaccess is also working well!
i am running this as virtual host in my local server!
This would allow people using on a port besides 80
to run Macaw.
I have a host with a website on the root path and an app on a folder. Need routes to work on the folder (not root in the server), but that folder is the route of the app. The issue is having / as path doesn't work and route needs to be /myapp/ to be able to route to the app root.
I would suggest to add a config var base_folder or something like that and internally manage all routes relative to that path. With current behavior I need to prefix /myapp on every route, and if I move the app to a different folder, also need to rewrite all routes vs. changing one config var.
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
Instead of
$uri_explode = explode('?', $uri);
No?
I have made a small site and want to use it as a virtual site in a subdirectory. Not sure if that is a good so i'll try to explain. I have one placeholdersite/server with a couple of subdirs. With a .htacces file on the root each domain is redirected to the subdir.
/placeholder.com
.htaccess
/domain1
- index.php
/domain2
- index.php
/domain3
- index.php
When I upload my site to this subdir and visit the site I only get a 404. On the local server everything work fine. I guess there is an issue with the path and I tried several things but most end in a server error.
Is there a way to get this working?
My Folder is
-Controller
---Demo.php
-vendor
-.htaccess
-index.php
My localhost url: http://localhost/test/macaw/
/------My .htaccess file-----
RewriteEngine On
RewriteBase /test/macaw/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [QSA,L]
-------/
My index.php file and my demo.php file like yours readme file (https://github.com/noahbuscher/Macaw/#example-passing-to-a-controller-instead-of-a-closure)
But I see 404 on my page.
Can you see where i make mistakes?
Thank you.
Are there any benchmarks available?
How can I alter the .htaccess file to append a trailing slash to an url automatically, as this is needed for Macaw to function properly?
For example: https://example.com/user should become https://example.com/user/ as we don't work with seperate files.
Alright, so I do not have the site on a subfolder so I set my htaccess to have:
RewriteBase /
Now, I am doing the following:
404 The page you requested was not found!'; }); Macaw::dispatch(); ?>I am only getting a response on the one without the slash. If I add a slash to my url to match the 'slug' method. I get the router error message.
There is the halts option in Macaw that for default is false. That means that even if a match is found, Macaw continues trying to match the current uri with other routes.
That makes me wonder, what happens if another route matches and the controller@action for the first match was already executed and provides some output? The second controller@action is also executed and provides output?
Looking at the code seems that $halts should be always true for a correct behavior.
You forgot to change namespace codingbean for noahbuscher in Packagist, so you can`t just install macaw using composer rule:
"noahbuscher/macaw": "dev-master"
every route gets an extra "/".
example: /home -> //home
I can just drop the slash, but I think that is not how it is intended.
I have tried several different ways to redirect with no success.
For example after a login
Url::redirect('dog/indexadmin');
And that method:
public static function redirect($url = null, $fullpath = false, $code = 200)
{
$url = ($fullpath === false) ? DIR . $url : $url; // tried commenting out
if ($code == 200) {
header('Location: ' . $url);
} else {
header('Location: ' . $url, true, $code);
}
exit;
}
DIR is just /mini4/. Tried without it. Also have tried many combinations:
Url::redirect('dog/indexadmin');
Url::redirect('/dog/indexadmin');
Url::redirect('http://localhost/mini4/dog/indexadmin');
Url::redirect('/mini4/dog/indexadmin');
Url::redirect('mini4/dog/indexadmin');
I just cannot seem to do a redirect.
If I, after logging in type the url in the address bar, it works, so routing is working, but no redirects.
The redirect method is from SMVC framework, from David Carr. But I even tried direct redirects using:
$url = 'dog/indexadmin';
header('Location: '.$url); // tried all the above in the variable.
die;
Please help.
hi,
i try to route some blog entrys like /post/2014/01/27/some_blog_entrys
but i think only the first entry on the str_replace matched?
my code is like:
Router::get('/post/(:num)/(:num)/(:num)/(:any)', function($year,$month,$day,$headline) {
echo "Year". $year . "<br/>";
echo "Month". $month . "<br/>";
echo "Day". $day . "<br/>";
echo "Headline". $headline . "<br/>";
});
output is this:
Year2014
Month
Day
Headline
27.01.2014,15:44:29,Missing argument 2 for {closure}(),/Applications/xampp/xamppfiles/htdocs/devlist/app/routes.php,18
27.01.2014,15:44:29,Missing argument 3 for {closure}(),/Applications/xampp/xamppfiles/htdocs/devlist/app/routes.php,18
27.01.2014,15:44:29,Missing argument 4 for {closure}(),/Applications/xampp/xamppfiles/htdocs/devlist/app/routes.php,18
27.01.2014,15:44:29,Undefined variable: month,/Applications/xampp/xamppfiles/htdocs/devlist/app/routes.php,20
27.01.2014,15:44:29,Undefined variable: day,/Applications/xampp/xamppfiles/htdocs/devlist/app/routes.php,21
27.01.2014,15:44:29,Undefined variable: headline,/Applications/xampp/xamppfiles/htdocs/devlist/app/routes.php,22
any option to fix this?
get, post, any are allowed methods, still if you do Macaw::lol(); it will work without complaining and you might get strange behaviors.
So if you miss one character, like Macaw::ge() it will call successfully and add an empty route.
Macaw::get('bug', function(){
echo "string";
});
127.0.0.1/bug
true
127.0.0.1/asass/bug
false
127.0.0.1/index.php/bug
true
but
127.0.0.1/index.php/asass/bug
true
Thanks for sharing this router, it's incredible!
Is their an option to set a callback to a controller rather then a closure? I would like the option to use a closure of call a class.
I can start adding some test. How do you see that?
behind modify the route and controller, show me unmatched routing in new version.
routes.php:
use \NoahBuscher\Macaw\Macaw;
Macaw::get('/', 'Controller\Home@home');
Macaw::dispatch();
home.php:(controller)
namespace Controller;
class Home extends BaseController
{
public function home() {}
}
How do i route the user to my error controller instead of showing plain text ?
my controller for 404 is located at app/controllers/error404.php
`
Find this line of code in โ PHP - s โ 404 error occurs
Original code
$uri = dirname($_SERVER['PHP_SELF']).'/'.$params[0]; //29
Modify code
$uri = strpos($params[0], '/') === 0 ? $params[0] : '/' . $params[0]; //29
Although I've proper configuration ( checked & reconfigured ), it fails to route. It always prints '404' only. I found a older version of it may be, and checked that, it was working. Whats the problem, how to fix it? And can we have a changelog? so that I can check which features I have in the older version and which Im missing..
I think it would be useful to be able to match a route, but to ignore the HTTP Request Method. Can you implement such a feature?
Can it be possible to alias some route to another, to allow '/
' mapping to '/(:any)'
with 'home'
as slug for instance.
Thanks
Please consider creating a composer package for macaw.
Is their any way to call a method inside a closure to bypass that route and for the next route to be checked like how slim does it:
$app = new \Slim\Slim();
$app->get('/hello/Frank', function () use ($app) {
echo "You won't see this...";
$app->pass();
});
$app->get('/hello/:name', function ($name) use ($app) {
echo "But you will see this!";
});
$app->run();
It would be cool to have something like this :
Macaw::map(['GET', 'POST'], '/page', function () {
echo 'Hello world!';
});
Thanks.
I encountered the following problems in accordance with the official document's nginx configuration.
That is the nginx error log:
unknown directive "RewriteEngine" in my-root-path/.htaccess:5
nginx.conf
autoindex off;
location / {
root D:/Projects/elasticsearch-test/public;
try_files $uri $uri/ /index.php?/$uri;
index index.html index.htm default.html default.htm index.php;
include my-root-path/.htaccess;
}
.htacess
RewriteEngine On
RewriteBase /
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [QSA,L]
Since you publish with composer, and some may clone your repo and call composer update, all PHP class autoloading behavior is ready to load your class.
see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
Thanks
Warning: preg_match(): Compilation failed: unmatched parentheses at offset 15 in D:\Work\www\routine\vendor\noahbuscher\macaw\Macaw.php on line 117
How to fix it?
cannot support with php cli mode
My route.php file contains:
Macaw::post('/api/pages/partials', 'EWS\API\Pages@getPartials'); Macaw::get('/api/pages/partial/(:num)', 'EWS\API\Pages@getPartial');
If I make a call to the API using /api/pages/partial/3 using the method GET everything works fine - so far so good.
If I now update the route file to contain:
Macaw::post('/api/pages/partials', 'EWS\API\Pages@getPartials'); Macaw::get('/api/pages/partial/(:num)', 'EWS\API\Pages@getPartial'); Macaw::put('/api/pages/partial/(:num)', 'EWS\API\Pages@updatePartial');
and again make the call to /api/pages/partial/3 using the method GET I get the error:
"Warning: in_array() expects parameter 2 to be array, null given in vendor/noahbuscher/macaw/Macaw.php on line 117"
Debugging the PHP shows that the call is matched as expected (and the getPartial routine is run) but it then continues to try and match the routes and when it gets to the put version the self::maps[$pos] is null so the error is thrown.
How can I have two identical routes but for different methods without this error occurring?
Thanks
I think $uri = dirname($_SERVER['PHP_SELF']).'/'.$params[0];
in line 29
should improve to
$uri = strpos($params[0], '/') === 0 ? $params[0] : dirname($_SERVER['PHP_SELF']) . '/' . $params[0];
or else
Macaw::get('/users/(:num)', 'Bee\Controllers\Users@show');
is not ok for http://127.0.0.1:8000/users/1
The server is opened by php -S 127.0.0.1:8000
Hi,
Is this possible to pass controller instead of function callback? Especially namespaced controller. Think it would be awesome
Thanks,
Bagus
Here https://github.com/noahbuscher/macaw/blob/master/Macaw.php#L135
There should be a:
if (!class_exists($segments[0]))
{
// error
}
I am attempting to test Macaw on localhost:8080 with the built-in PHP server using a router script as shown here:
http://php.net/manual/en/features.commandline.webserver.php#example-383
The issue is that no url except the root ('/') is matching. Even if I have defined a route by:
Macaw::get('/test', function () {
echo 'this is a test';
});
It gives me 404. Only the route:
Macaw::get('/', function () {
echo 'hello';
});
actually seems to be working. I also get a warning: undefined offset "1" on line 73, if that helps.
Thanks.
//wechat
Macaw::any('/wechat','WechatController@index');
when the uri is hostname/wechat?signature=db8a6d1d5855
var_dump($_GET);
the result is array(1) { ["//wechat"]=> string(0) "" }
How can i use the global variable in the controller.
thank you
Can i use it for routes group like laravel's route as below :
Route::group(['namespace' => 'Admin'], function()
{
// Controllers Within The "App\Http\Controllers\Admin" Namespace
Route::group(['namespace' => 'User'], function() {
// Controllers Within The "App\Http\Controllers\Admin\User" Namespace
});
});
or
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () {
// Uses Auth Middleware
});
Route::get('user/profile', function () {
// Uses Auth Middleware
});
});
Let's say I invoke Macaw using the following index.php
file through cURL:
<?php
require_once __DIR__.'/Macaw/macaw.php';
Macaw::put('/(:any)', function($slug) {
echo "SLUG = " . $slug;
});
$ curl -v -i -X PUT -T "somefile" http://localhost/\~${USER}/macaw/index.php/this/is/a/test/
The $slug
value in the put
route is 'somefile'
and not 'this/is/a/test/somefile'
as expected. Why?
On this line https://github.com/noahbuscher/macaw/blob/master/Macaw.php#L126
Macaw is splitting the callback for controllers that have this form "\controllers\ControllerX@action" using "/" which is a character that doesn't appear in controller based callbacks. So I'm not sure if this is an undocumented feature or is code that can be removed.
Hi!
Could you tell me how to make a 404 error page through your router. For example, instead of the plain text "404" on an empty page, another page was loaded - at /404/
with the same or its template?
For example, I create this page with path /404/
:
Macaw::get('/404/', '\Controllers@error404Page');
In Controllers.php I add a function:
public function error404Page()
{
header($_SERVER['SERVER_PROTOCOL'] . " 404 Not Found");
$this->layout = Template::getInstance('error404.tpl');
$this->layout->set("title", "404 Error - Not found");
$this->layout->set("content", '404 Error: Oops! Nothing found');
echo $this->layout->output();
}
In this case, we open the page /404/
, but it gives the code 200
, since the router is specified.
Thanks!
hi there,
it would be nice to have a setting telling router not to process other routes when match is found.
consider following example:
Macaw::get('/admin/(:any)', 'Controller_Admin@index');
Macaw::get('/(:any)', 'Controller_Index@view');
currently those two actions are invoked which is not correct in some cases.
regards
It seems there should be a function map() that when called statically adds items to $maps, but that is not documented. So not sure $maps is even used for something. Can it be removed?
uri:/debug/detail
self::$routes:Array
(
[0] => /debug/debug
[1] => /debug/debug/detail
)
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.