How to allow dots in Slim 3 or nikic/FastRoute parameters? - php

I am using Slim 3, which uses nikic/FastRoute, and am having trouble with an endpoint like so:
$app->get('/count/{url}', function ($request, $response) use ($curl) {
$controller = new Proximate\Controller\CountUrl($request, $response);
$controller->setCurl($curl);
return $controller->execute();
});
My plan is to pass an urlencoded URL into {url} and inject that into the controller. For example, for http://www.example.com, the request would be:
curl \
--verbose \
http://localhost:8080/count/http%3A%2F%2Fwww.example.com%2F
However, this fails with a 404, so is evidently not matched. This also fails:
curl \
--verbose \
http://localhost:8080/count/http%3A%2F%2Fwww.
However, oddly, this does match (i.e. without the trailing dot):
curl \
--verbose \
http://localhost:8080/count/http%3A%2F%2Fwww
I originally thought it was the urlencoded slashes that was confusing it (%2F) but having tried it without these characters, I find that in fact it is the dot, anywhere in the string. Why does this not match, and do I need a regex match in order to get this to work?
I am using the PHP built-in web server for this app.

After a bit more digging, I find that this is caused by the PHP built-in web server, and is not a Slim or FastRoute issue at all. Here is the Slim bug report and here is one for PHP.
Sadly the core PHP team have marked as Won't fix, since the server is only for testing. Personally, I think the warnings about not using this server for production are a bit overblown (my Docker containers remain of a reasonably manageable size because I am not throwing Apache in there as well).
Thankfully there is a fix for this - specifying the script name in the URL will cause PHP to pass the rest of it correctly to the routing system. Like so:
curl \
--verbose \
http://localhost:8080/index.php/count/http%3A%2F%2Fwww.example.com%2F
# ^^^^^^^^^
# Script name
Of course, this is not very elegant, so I may yet switch to another solution. I've not tried it yet, but this PHP-only web server looks quite promising.

Related

Why is PHP Curl returning T_CONSTANT_ENCAPSED_STRING?

I'm attempting to use PHP to get data from CallRail.com API via JSON.
However, I'm getting this error when previewing my PHP file directly in my browser: T_CONSTANT_ENCAPSED_STRING
My code:
<?
curl -H "Authorization: Token token={my-token-id}" \
-X GET \
"https://api.callrail.com/v2/a/{my-account-id}/calls.json"
?>
So far I have:
Read several articles related to the error without finding a solution or verifiably accurate explanation.
I've manually retyped all of the code to ensure I didn't have any improperly encoded characters or invalid white spaces.
I've also attempted to locate official documentation in the PHP docs but not found anything helpful.
And I've tested this in a blank PHP file so the code is completely isolated.
I don't know how to further debug this issue and am hoping someone can either identify the problem or share the steps to debug this on my own from this point.
Your code sample is binary, to be executed from the command line in a shell like Bash, not PHP. This is why you're getting that error.
If you want PHP to call an external binary use exec(), shell_exec() or system().
Also, for portability, don't use the short open tags, ever, because it depends on the short_open_tag php.ini directive, or whether or not PHP was compiled with --enable-short-tags.
Even if your code doesn't have to be portable, it's just a bad habit. In case you ever need to work with some portable PHP code in the future; try:
<?php
echo shell_exec('curl -H "Authorization: Token token={my-token-id}" -X GET "https://api.callrail.com/v2/a/{my-account-id}/calls.json"');
Or if you want it on multiple lines, you could use implode:
<?php
echo shell_exec ( implode ( " ", [
'curl',
'-H "Authorization: Token token={my-token-id}"',
'-X GET',
'"https://api.callrail.com/v2/a/{my-account-id}/calls.json"'
] ) );

Compile C++ file Using PHP

I am using PHP on Windows machin. I also use Dev C++. I can perfectly compile .cpp file on CMD using this command:
g++ hello.cpp -O3 -o hello.exe
Now what I am trying to do is running the same command using php system() function, so it looks like this:
system("g++ c:\wamp\www\grader\hello.cpp -O3 -o C:\wamp\www\grader\hello.exe");
but it doesn't compile. I am lost, please tell me what am I missing?
I also looked up at this question and thats exactly what I need, but I couldnt find a usefull solution for my case there:
Php script to compile c++ file and run the executable file with input file
Use the PHP exec command.
echo exec('g++ hello.cpp -O3 -o hello.exe');
should work.
There's a whole family of different exec & system commands in PHP, see here:
http://www.php.net/manual/en/ref.exec.php
If you want the output into a variable, then use :
$variable = exec('g++ hello.cpp -O3 -o hello.exe');
If that doesn't work, then make sure that g++ is available in your path, and that your logged in with sufficient enough privliges to allow it to execute.
You may find also that it's failing beacuse PHP is essentially being executed by your web server (Unless your also running PHP from the cmd prompt) , and the web server user ID may not have write access to the folder where G++ is trying to create the output file.
Temporarily granting write access to 'Everybody' on the output folder will verify if that is the case.
Two things:
You are using double quotes and are not escaping the \ inside the path.
You are not using a full path to g++.
The first one is important as \ followed by something has a special meaning in such a string (you might know \n as new line), the second one is relevant since the PHP environment might have a different search path.
A solution might be
system("c:\\path\\to\\g++ c:\\wamp\\www\\grader\\hello.cpp -O3 -o C:\\wamp\\www\\grader\\hello.exe");
Alternatively you can use single quotes, intead of double quotes, they use diffeent,less strict escaping rules
system('c:\path\to\g++ c:\wamp\www\grader\hello.cpp -O3 -o C:\wamp\www\grader\hello.exe');
or use / instead of \, which is supported by windows, too.
system("c:/path/to/g++ c:/wamp/www/grader/hello.cpp -O3 -o C:/wamp/www/grader/hello.exe");
What you do is your choice, while many might consider the first one as ugly, and the last one as bad style on Windows ;-)
Thanks to everyone. I tried to run the codes given in above posts and it worked like a charm.
I ran the following code using my browser
$var = exec("g++ C:/wamp/www/cpp/hello.cpp -O3 -o C:/wamp/www/cpp/hello.exe");
echo $var;
The exe file is created. I am able to see the result when i run the exe file but the problem is when i run the above code in the browser, the result is not displayed on the webpage. I gave full access permission to all users but still give does not show the result on the webpage.
I really need help on this since i am doing a project on simulated annealing where i want to get the result from compiled c++ program and display it in the webpage with some jquery highcharts.
Thanks again to all, it has helped me alot and i have learnt alot as well.

Is it possible to have vim prevent the saving of a php file that has a parse error?

I use vim and would like it to prevent me from saving php files that has parse errors. If I would like to use for instance "php -l <file>" to achieve this, how would the autocmd in .vimrc look like?
I know I can hook into BufWritePre with something like
autocmd FileType php autocmd BufWritePre * !php -l %
but I want it to abort the "write" if the php command fails.
You can throw an uncaught exception in the hook and it will abort write: try
function s:RunPHP()
execute '!php -l' shellescape(#%, 1)
if v:shell_error | throw 'PHP failed' | endif
endfunction
function s:DefineBWPphpevent()
augroup Run_php
autocmd! BufWritePre <buffer> :call s:RunPHP()
augroup END
endfunction
augroup Run_php
autocmd!
autocmd FileType * :autocmd! Run_php BufWritePre <buffer>
autocmd FileType php :call s:DefineBWPphpevent()
augroup END
Also note
shellescape: you should not use :!shell_command % as here vim does not do proper escaping and you will run into troubles if file name contains special symbols like spaces, quotes, dollar, newlines, ...
<buffer> in place of * in second pattern. Your original command does not define autocommand for php files, it instead defines autocommand for all filetypes if one of the filetypes is php.
autocmd grouping and banged :autocmd!s: they prevent duplicating autocommands.
By the way, what do you want to achieve by running php on old version of file (it is BufWritePre event, so it happens before file is written)? Maybe you should replace code that runs php with :w !php -l, :w !php -l - or even :w !php -l /dev/stdin depending on what php accepts (I do not have it on my system and do not want to have).
but I want it to abort the "write" if the php command fails.
As far as I know, this isn't possible with VIM. Documentation doesn't state this capability either, so I'm pretty sure that can't be done, without a hack. The question is though what you're trying to accomplish? I have a script that makes sure I have no parse errors in PHP before I commit to version control, instead of when I save the file. That's a simple pre-commit hook, perhaps that something that'll work?
If you're really interested in linting before you save the file, you might be able to rewrite "ZZ" and ":w" to a command you wrote yourself, that in turns lints the file (in case of a PHP file) and saves upon no errors. I'm not sure if you can remap the :w, and it might cause more issues than it solves though.
Perhaps a simpler solution would be to create a command on a keystroke you choose yourself (e.g. F5), and make that do what you want?

How to pass (cli) arguments by file in Ant

I'm using Ant to build my project, generate docs and check coding strandard violations. I use some external tool through exec task. Exec prefixes the output lines with [exec]
This string messes my output up.
If I specify the -e switch in the command line, it remains quiet.
Is there a way to
specify the -e switch on every run in the build.xml file?
or something else equivalent.
Maybe the Java System Properties will help ... see http://ant.apache.org/manual/running.html#sysprops
In particular, I think that setting the property build.compiler.emacs to true may help. Anyway, I doubt that setting (or, re-setting it via ant-extensions) it in the build file helps, as properties are designed to be immutable.

Validate if an application is at the server

I have an own webserver and for one of my clients I need to be able to search through PDF's. I've asked my hostingprovider to install the xPDF package. Now I've come to testing and I'm calling this line of code in a PHP script:
$content = shell_exec('/usr/local/bin/pdftotext test.pdf -');
The only thing is, I'm getting a NULL result with. So, my question, is there a way to validate if the program is really installed? Btw, I'm not even sure if the path is correct. I'm pretty new if it comes to having an own webserver. I've taken this example from : http://davidwalsh.name/read-pdf-doc-file-php
If you have shell access, log in using SSH, and try
whereis pdftotext
if the only thing you get is a
pdftotext:
then it is most likely not (or not properly) installed.

Categories