Asked same question at stackoverflow. Thought it makes sense to ask here.
Im lost with the phalcon regex routes pattern.
I want to get the id (f.e.)
url/foo/bar/baz/some123id
So id can be anything but count and find.
Usually you get this via a path /foo/{id}
But i need a pattern to exclude the words find and count.
Example code
class EntityController extends \Phalcon\Mvc\Controller
{
public function get($id)
{
return $this->response->setStatusCode(200, "OK")
->sendHeaders()
->setContent("TEST: get entity by id {$id}")
->send();
}
public function count()
{
return $this->response->setStatusCode(200, "OK")
->sendHeaders()
->setContent("TEST: count entities")
->send();
}
public function find()
{
return $this->response->setStatusCode(200, "OK")
->sendHeaders()
->setContent("TEST: find entities")
->send();
}
}
$app = new \Phalcon\Mvc\Micro();
$app->notFound(
function () use ($app) {
$app->response->setStatusCode(404, 'Not Found');
$app->response->sendHeaders();
$message = 'Route Not Found';
$app->response->setContent($message);
$app->response->send();
}
);
$entities = new \Phalcon\Mvc\Micro\Collection();
$entities->setHandler(new EntityController());
$entities->get('/bom/count', 'count');
$entities->get('/bom/find', 'find');
// usually search by id (does not work)
// $entities->get('/bom/{id}', 'get');
// does not work with /123c (c is in "count")
// $entities->get('/bom/{id:[^count|find]+}', 'get');
// should actually work (as of PHP regex) but does not
$entities->get('/bom/{id:^(?!^count$|^find$).+}', 'get');
$app->mount($entities);
$app->handle();
// Tests
// curl -v url/bom/count
// TEST: count entities
// curl -v url/bom/find
// TEST: find entities
// curl -v url/bom/abc123
// Route Not Found
The pattern ^(?!^count$|^find$).+} works with PHP.
PHP Pattern Test
$format = "%-20s%-20s%-20s\r\n";
echo sprintf(
$format,
"Subject",
"Does match",
"Expect match"
);
$pattern = "^(?!^count$|^find$).+";
foreach (
[
'sku' => true,
'count' => false,
'find' => false,
'countfind' => true,
'findcount' => true,
'skucount' => true,
'skufind' => true,
'countsku' => true,
'findsku' => true,
'coun' => true,
'fin' => true,
'ount' => true,
'ind' => true,
'skucoun' => true,
'skufin' => true,
'finsku' => true,
'counsku' => true,
] as $subject => $expectMatch
) {
$matches = [];
$doesMatch = preg_match("/{$pattern}/", $subject, $matches);
echo sprintf(
$format,
$subject,
$doesMatch,
var_export($expectMatch, true)
);
}
// Subject Does match Expect match
// sku 1 true
// count 0 false
// find 0 false
// countfind 1 true
// findcount 1 true
// skucount 1 true
// skufind 1 true
// countsku 1 true
// findsku 1 true
// coun 1 true
// fin 1 true
// ount 1 true
// ind 1 true
// skucoun 1 true
// skufin 1 true
// finsku 1 true
// counsku 1 true
What am i missing here?