noodlehaus / dispatch Goto Github PK
View Code? Open in Web Editor NEWa tiny library for quick and easy PHP apps
a tiny library for quick and easy PHP apps
If a route defined like "/edit/:aval" has a query string parameter with the same name as the named parameter then the query string parameter is overwritten by the route parameter.
e.g. with the example above if the URI is /edit/1234?aval=5678 then a call to param('aval') returns 1234 as the QSP of the same name with value 5678 is overwritten.
Problem originates in the param() function called in the on() function:
// used by on() for merging in route symbols.
$source = array_merge($source, $name);
The merge overwrites GET/POST symbols with the same key name.
(I added a separate rparam() function in my application and kept the route params completely separate to GET/POST)
If this limitation is intentional then it would be useful to add a note in the user guide warning people to choose non-colliding names.
after PHPUnit tests are done.
just so it doesn't ruin global.
I have put the json-Example on my dev-system to work, with the appropriate changes. Source looks like this:
<?php
require_once __DIR__ . '/../vendor/autoload.php';
config('source', __DIR__ . '/../config.local.ini');
before(function () {
var_dump('#moo');
scope('object', array('name' => 'Dispatch', 'type' => 'Framework'));
});
on('GET', '/json', function () {
json(scope('object'));
});
on('GET', '/jsonp', function () {
json(scope('object'), 'callback');
});
dispatch();
I had to notice that the scope('object')
returns null
on the first route (/json
), but works fine on the other one (/jsonp
). I added the var_dump
in case this was a problem with scope
, but the dump does not appear when calling the /json
route. I'm using the dev-master
version from composer. The config.ini
only sets a dispatch.url
, which I don't think matters here.
Hello.
I'm not quite sure about whats the difference between "layout" and "view". In the render function the first parameter is ignored except when the third one is set to false.
Exactly backwards what is wrote on the documentation.
for example, if i execute render('view', array()); the layout loaded is "layout.html.php" in the views directory not the view.html.php as it's expected. Right?
To change the file included from the views folder, i have to set the third parameter, making the first one, even more useless.
render('view', array(), 'custom_view');
I'm not sure, if this is the expected behavior or not. If it is, the docs are not correctly explained, and i'm the first one who wanna know whats the difference between "view" and "layout".
Thanks!
publish a composer package
to prevent broken code being pushed to master.
If the request body content-type is application/json, that's the only time when it's decoded values should be merged into params().
Hey @noodlehaus, I've really been enjoying using Dispatch for several projects I started this month, but in developing my latest project I realized I needed a slightly more robust templating framework, but I wanted to keep the mustache like syntax, so I rewrote your dispatch-mustache addon to use Handlebars.
You can find it here https://github.com/GiggleboxStudios/dispatch-handlebars and feel free to link it up in your docs if you want :)
It's a quite simple problem I notices when I was refactoring my code. I changed the closures from
on('GET', '/bla', function () {
// Hic sunt ponies
});
to
on('GET', '/bla', 'getBla');
Suddenly my router gave me a 404
for every URL. After trying every call of on
separately, I found out that when you feed the function the name of an undefined function (typo, import error), the router will only stop adding new routes beyond that point and will give only 404.
It would be much better if the function would output some kind of runtime error to make debugging this easier.
I will perhaps look into the issue later when I have the time.
Hi,
Can I add a library ? And how to add it ?
Hi,
there is a problem with php 5.3 and Array declaration in Dispatch. Especially at line 22 and line 490 you define an array variable with '[]' but this cause an error in PHP < 5.4. Can you fix this?
Great Job!
Thank you
hi there
i currently move a small redirector app from dispatch 1 to dispatch 2
i try to map the /index route but it always gives me a 404 Page not found back
I'm using the example code in the page. do you have an idea? when i call
redir.lo the 404 gets out
redir.lo/index and i hit the defined on route.
I think we had some magic to use the /index route as / right?
/bastian
God Domingo for Dispatch. I like your microframework very much, it let me like to write the code on nodejs. Thx very much.
PHP Version 5.3.6
I find it can't dipsay flash example correctly.
So I print the cookie '_F' and found out the quotes in json string from cookie are slashed. ex: " '.. it leads to the json_decode returns null.
I try to modify the dispatch code, add 'stripslashes', to fix it out, sorry it failed.
Did you meet this error before?
Fatal error: Call to undefined function finfo_open() in \vendor\dispatch\dispatch\src\dispatch.php on line 371
Seems to be an issue that my PHP instance does not have fileinfo
installed...
$ php -v
PHP 5.4.12 (cli) (built: Feb 21 2013 17:44:16)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
phpinfo() | |
---|---|
Version | PHP 5.4.12 |
Build Date | Feb 21 2013 17:41:51 |
Compiler | MSVC9 (Visual C++ 2008 |
Architecture | x64 |
Configure Command |
|
the lib contains
$responder = serve(context(), $verb, $path, ...$args); $responder();
causing PHP Fatal error: Function name must be a string in dispatch.php on line 28.
Can you help how to fix it.
Right now, middleware functions have no way of forwarding values down the chain, except via stash(...)
. It might be good to allow value passing via the next(...)
call.
function jwt_verify(callable $next) {
# ...
$data = jwt_decode(...);
return $next($data);
}
This passed parameter then gets appended to the list of args that gets passed down the chain. Succeeding middleware and handlers can then access this additional parameter from the tailing ...$args
.
Great job!
But as far as is understood the library, Apache mod_rewrite is required and I haven´t seen any documentation stating this subject and a simple example of a .htaccess file.
If I'm wrong and apache mod_rewrite is not required, how does the library process the requests that would throw a 404?
For example:
A request for http://site.com/a/b/1
Apache will try to find a subdirectory in the virtual root directory with the path "/a/b/1".
How does dispatch get this request, if the code with the mappings is located in the file "/index.php"?
Thanks.
Right now, there's still no way to specify handlers that get executed whenever:
serve(...)
doesn't find a route match (404)serve(...)
encounters an error or exception during handler execution (500)Probable approach for this would be to:
apply(...)
, eg. apply(404, page('error404'))
trap(404, page('error404'))
For question problem 3, maybe use something like return error(422, 'not-processable-template')
within handlers for triggering error codes.
feature to get named parameters from $_REQUEST pass to handler function.
i mean when define handler callback function
map('GET', '/topics/<id>', function ($id) {
// will get the id from pathinfo
});
there's some code using ReflectionFunction to get the parameters from the handler callback function , and auto get the value from $_REQUEST. https://github.com/lloydzhou/router/blob/master/router.php#L56
The name of the function 'match' have to be changed because there is a data structure introduced by PHP 8 having the same name
(see https://www.php.net/manual/de/control-structures.match.php)
Running Dispatch in my local dev environment using PHP's built-in server causes ~1+sec of latency to the page response. Just switched a few of my routes over to https://github.com/bramus/router and now I'm seeing page response times on those routes of ~330-560ms.
The only change I made was the router library running things, everything else in my app, IO, DB, template rendering, etc was unchanged.
I'll see about coming up with a couple of test cases to validate this, but I'm curiuos if Dispatch's internal route management is just inheritely inefficient?
I will try to get work on that done during the weekend.
Dispatch 5 will change the API entirely and move from global functions and closures to singletons and proper OO for routing.
The main elements of dispatch for me are:
This issue is to collect some ideas and discuss them. Please wait for the code draft in my Repo before commenting on implementation.
I have a the problem that I can't make a file download path. The error I'm getting is this:
PHP Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 7344128 bytes) in vendor/dispatch/dispatch/src/dispatch.php on line 392
It doesn't matter how I set my memory limit, the function always exceeds it. I tested with up to 128M
. My code is similar to this:
on('GET', '/file', function () {
nocache();
$db = scope('db');
$file_id = params('id');
$row = $db->files()->where('id', $file_id)->limit(1)->fetch();
if($row === false) {
error(404);
} else {
send($row['file_path'], $file_id . '.bin');
}
});
Using dev-master
of dispatch
and the only other library in use is notORM.
I checked that $row['file_path']
exists. The smallest file I have tested it with has 500 KB, and it still occurs. Maybe I did wrong in the call?
need to add support for this
Hi!
I need to use the application inside a folder on the server (ex: \public_html\app), but it has 404 errors. It works normally at the root, and I can't use it on the root because it conflicts with the main app (made with Laravel).
I saw in previous releases that there was a config to support this function, but even adapting the code to use an old version, I was not successful.
Does anyone have a tip on how to make it work on a folder?
Below is a snippet of the code:
##index.php##
<?php
require 'lib/dispatch.php';
require 'mysqldbadapter.php';
route('GET', '/', function ($db) {
header('Location: /index.html');
});
route('GET', '/getActive', function ($db) {
$json = json_encode($db->getSurveys());
return response($json, 200, ['content-type' => 'application/json']);
});
$db = new MysqlDBAdapter();
dispatch($db);
##mysqldbadapter.php##
<?php
class MysqlDBAdapter {
private $dbh;
public function __construct() {
$this->dbh = new PDO("mysql:host=127.0.0.1;port=3306;dbname=user;user=root;password=123");
}
public function getObjectFromStorage($storageId) {
$sqlQuery = 'SELECT * FROM ' . $storageId;
$data = array();
$sql = $this->dbh->query($sqlQuery);
while($result = $sql->fetch(PDO::FETCH_ASSOC)) {
$data[$result['id']] = $result;
}
return $data;
}
public function getSurveys() {
return $this->getObjectFromStorage('surveys');
}
}
Since php://input can only be read once.
Hi, quick question,
what is the alternative to the before() method in the latest release?
I have deployed a dispatch site at root.com/sub/ but it's keep redirect to root.com. I'm using nginx as a web server and it's config is correct. I tried echoing a "hello world" from root.com/sub/index.php it works but doesn't work with dispatch.
need to use PHPUnit instead of adhoc tests. might need code changes as well, make things more testable.
More of a note for anyone trying to leverage less.js in the browser for their dev environments. Make this change in your projects root .htaccess
file:
<IfModule mod_rewrite.c>
RewriteEngine on
# in this case, our app bootstrap file is index.php
RewriteRule !\.(js|html|ico|gif|jpg|png|css|less)$ index.php
</IfModule>
Adding |less
to your rewrite rule will allow the server to deliver .less
files to the browser.
Edit: The same thing goes for any mime types that aren't whitelisted by this rewrite rule.
eg: mp3|mustache|handlebars|json|jpeg|ogg|mp4|wav|wmv
etc.
Although the download()
function is better suited for media formats, and a proper endpoint that the backend could facilitate for template dumps to ajax requests wouldn't be out of the question.
inline comments that's compatible with PHPDocs/Doxygen
map('/quiz/question/{action}/{?id}', function ($args=null)
I want the id to be an optional parameter in the url, but it isn't working. Also how do I retrieve the queries in the url like site.com/quiz/question/edit?id=123 where I want to retrieve id. I tried params['id'] and args['id'].
I can not do route to addresses '/'
include __DIR__.'/vendor/dispatch/dispatch.php';
get('/', function(){
render('index', null, false);
});
dispatch();
do not work for me.
Trying to add url arguments to a route, and it breaks the route handling.
<?php
// http://localhost:3005/login?wafklds > works
// http://localhost:3005/login?wafklds=wjdfkls > doesn't work
map('GET', BASE_URL.'/login', function() {
echo 'login';
});
When executing against PHP 5.3.13, the array declaration using the brackets syntax [] provoke the error :
Parse error: syntax error, unexpected '[' in (...)
Replacing [] by array() should resolve the issue.
Basically I want something like this:
filter('task', function($taskId) {
return Task::find($taskId);
});
// GET /tasks/123
on('GET', '/task/:task', function($task) {
// Passed value is the result of the filter
assert(is_null($task) || $task instanceof Task);
// Original value still available in params(): 123
params('task');
});
The downside - we can have more than one filter per param - I'm not sure what the best solution would be for that. I guess either:
Passing the result of one filter to the next, or the original value if nothing is returned (only makes sense if every filter returns a value),
foreach ($filters as $symbol => $callback) {
$res = call_user_func($callback, $val);
if (!is_null($res)) $val = $res;
}
Passing the original value to each filter, and passing an array of filtered values if more than one filter returns something.
// Get the results of the filters
$results = [];
foreach ($filters as $symbol => $callback) {
$res = call_user_func($callback, $val);
if (!is_null($res)) $results[] = $res;
}
// Decide what to pass to the on() callback
switch (count($results)):
case 0:
// No filters returned values, pass original value
$values[$symbol] = $val;
break;
case 1:
// 1 filter returned a value, pass this on it's own
$values[$symbol] = array_shift($results);
break;
default:
// More than 1 filter returned a value, so pass an array
$values[$symbol] = $results;
break;
}
...
call_user_func_array($on, $values);
I'll probably hack something up, but do you have any thoughts on this?
I see the given example of a blog is working perfectly, but is there any way I can put custom "title" tags which is defined in dispatch/example/views/layout.phtml. How can I put $post['title'] from dispatch/example/views/post.phtml in the header title tags instead of a common title for all pages?
In the same way, I want to put custom keywords and description meta tags. How can I pass these variables from post.phtml to layout.html?
Hey there,
if I'm using dispatch in an subdirectory like this: example.com/dispatch-test/
It won't accept
map('/','handler');
I must do it like that:
map('dispatch-test/','handler');
Is this the only way of doing this, or is there a smarter way?
Hey guys,
where has the site_url() function gone? I can't find it in the latest version!?
Cheers,
Simon
I need to return an image generated with jpgraph from a specific path.
How is done?
Thanks
Luca
Please add Namespace in dispatch.php
Reason
Avoid function name conflict.
Right now we can not create another function with the name that already exists in dispatch.
Solution
Add Namespace
// dispatch.php
<?php
namespace Dispatch;
?>
Usage
<?php
include '../../src/dispatch.php';
use Dispatch as app;
app\on('GET', '/index', function () {
echo "GET /index invoked";
});
app\dispatch();
?>
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.