Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuration issue? #176

Closed
brettalton opened this issue Jan 20, 2014 · 14 comments
Closed

Configuration issue? #176

brettalton opened this issue Jan 20, 2014 · 14 comments
Assignees

Comments

@brettalton
Copy link

I know this isn't a "I can't get this working" forum, but I've found it very difficult to get started with this project.

I have an index.php file inside demo-brett/listing with the following .htaccess

# from https://gist.github.com/chriso/874000

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

I'm using the single-file implementation to skip the autoloading headache like so,

/**
 * PHP Router called Klein (v2.0.2)
 *
 * Website:
 *      https://github.com/chriso/klein.php
 * Single file implmentation:
 *      https://raw2.github.com/gbouthenot/klein.php/K2-singlefile/src-single/klein.php
 * Readme:
 *      https://github.com/chriso/klein.php/blob/v2.0.2/README.md
*/
require_once('klein.php');

$klein = new \Klein\Klein();

But I can't seem to respond to absolutely anything, except for the generic "everything" response.

$klein->respond('/[:name]', function ($request) {
    return 'Hello ' . $request->name;
});

$klein->respond('GET', '/', function ($request) {
    return '[GET]';
});

$klein->respond('POST', '/', function ($request) {
    return '[POST]';
});

$klein->respond('GET', 'hello-world', function ($request) {
    return '[GET 1] Hello world';
});

$klein->respond('POST', 'hello-world', function ($request) {
    return '[POST 1] Hello world';
});

$klein->respond('GET', '/hello-world', function ($request) {
    return '[GET 2] Hello world';
});

$klein->respond('POST', '/hello-world', function ($request) {
    return '[POST 2] Hello world';
});

$klein->respond('/[:name]', function ($request) {
    return 'Hello ' . $request->name;
});

$klein->respond(function () {
    return 'All the things';
});

I'm then dispatching the response of course, but all I ever receive is All the things

/**
 * Generate response
 */
$klein->dispatch();

I have all the variables dumping at the bottom and nothing seems to be contained in $_GET or $_POST, only in $_SERVER

/**
 * Temporary profiling
 */
echo '<pre>';
var_dump($_GET);
var_dump($_POST);
var_dump($_SERVER);

If I visit http://localhost/demo-brett/listing/hello-world, I receive the following output,

array(0) {
}
array(0) {
}
array(31) {
  ["REDIRECT_STATUS"]=>
  string(3) "200"
  ["HTTP_HOST"]=>
  string(24) "localhost"
  ["HTTP_CONNECTION"]=>
  string(10) "keep-alive"
  ["HTTP_CACHE_CONTROL"]=>
  string(9) "max-age=0"
  ["HTTP_ACCEPT"]=>
  string(74) "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
  ["HTTP_USER_AGENT"]=>
  string(119) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
  ["HTTP_DNT"]=>
  string(1) "1"
  ["HTTP_ACCEPT_ENCODING"]=>
  string(17) "gzip,deflate,sdch"
  ["HTTP_ACCEPT_LANGUAGE"]=>
  string(26) "en-CA,en;q=0.8,en-US;q=0.6"
  ["SERVER_NAME"]=>
  string(24) "localhost"
  ["SERVER_ADDR"]=>
  string(13) "127.0.0.1"
  ["SERVER_PORT"]=>
  string(2) "80"
  ["REMOTE_ADDR"]=>
  string(11) "127.0.0.1"
  ["DOCUMENT_ROOT"]=>
  string(51) "/Users/brett/www/"
  ["SERVER_ADMIN"]=>
  string(14) "root@localhost"
  ["SCRIPT_FILENAME"]=>
  string(79) "/Users/brett/www/demo_brett/listing/index.php"
  ["REMOTE_PORT"]=>
  string(5) "63737"
  ["REDIRECT_URL"]=>
  string(31) "/demo_brett/listing/hello-world"
  ["GATEWAY_INTERFACE"]=>
  string(7) "CGI/1.1"
  ["SERVER_PROTOCOL"]=>
  string(8) "HTTP/1.1"
  ["REQUEST_METHOD"]=>
  string(3) "GET"
  ["QUERY_STRING"]=>
  string(0) ""
  ["REQUEST_URI"]=>
  string(31) "/demo_brett/listing/hello-world"
  ["SCRIPT_NAME"]=>
  string(29) "/demo_brett/listing/index.php"
  ["PHP_SELF"]=>
  string(29) "/demo_brett/listing/index.php"
  ["REQUEST_TIME"]=>
  int(1390244324)
}

Does anyone know what may be occurring?

@ghost ghost assigned Rican7 Jan 20, 2014
@Rican7
Copy link
Member

Rican7 commented Jan 20, 2014

I shouldn't really be supporting a fork of the project, as the code could be modified and doing plenty of other things, however I think I know what may be the problem.

Klein uses a request's pathname() to match, which comes from the REQUEST_URI server variable. As you can see from your environment copy-pasta (thanks, by the way, it makes helping much easier), your REQUEST_URI is "/demo_brett/listing/hello-world", which won't match any of your defined routes. To remedy this situation of installing via a subdirectory, I suggest reading this wiki document.

Finally, I don't know why people don't use autoloading, its an important feature used in modern PHP and with composer. It usually increases performance, and its also a PSR-0 standard. You don't need to write an autoloader, just use one. Also, using a fork is going to be a headache, as you're going to have to wait for any bugfixes and your dependencies won't be managed. Check out a tutorial or something and start using composer. Seriously, it'll change everything: http://net.tutsplus.com/tutorials/php/easy-package-management-with-composer/

@brettalton
Copy link
Author

So it was a subfolder issue.

It appears if I add this to the top of my index.php file, it fixes the issue.

$base  = dirname($_SERVER['PHP_SELF']);

// Update request when we have a subdirectory
if (ltrim($base, '/'))
{
    $_SERVER['REQUEST_URI'] = substr($_SERVER['REQUEST_URI'], strlen($base));
}

And I was able to get rid of the manual RewriteBase in my .htaccess file.

I'm wondering if some sort of documentation can be written for using Klein with subfolders? It would have saved a massive amount of frustration.


As for Composer...

I'm on a shared server that doesn't support Composer and since this is a small project for work, I had to use this workaround. Believe me, I use a PSR-0 autoloader on my projects (or ones that come with most projects, like Laravel).

I believe using a single-file/non-autoloader version of the library is a fair workaround.

@Rican7
Copy link
Member

Rican7 commented Jan 20, 2014

Yea, I figured that would work. The documentation is written, its in the Wiki. :)
README's can only go so far, and this project's is pretty extensive.

Ah, that's too bad. Composer is a pretty compatible binary, I'm surprised. Yea, its a work-around, but I wouldn't call it a good one. Implementing a PSR-0 compatible autoloader will save you more pain later (manual require statements are cumbersome) and its barely any code: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md#example-implementation

@Rican7 Rican7 closed this as completed Jan 20, 2014
@brettalton
Copy link
Author

I would figure that the README should have more to do with configuration and the wiki have more to do with examples than visa versa. I found the library hard to install and understand based on two factors: (1) It doesn't support sub-directories, which I'm surprised hasn't come up more often because only live projects usually site in the root directory and, (2) There isn't documentation on how to implement the autoloader.

I know of how to implement the autoloader but the example given assumes vendor/autoload.php exists and that Klein exists as vendor/Klein/Klien.php, where as a more realistic setup is to have the git repository pulled into vendor/ which would site as vendor/klein.php/src/Klein/Klein, which then doesn't work with the autoloader.

When I have time I'll see if I can adjust the README to help with installation/use first before diving into examples.

@Rican7
Copy link
Member

Rican7 commented Jan 20, 2014

Most PHP libraries have examples in their README. Its the un-written standard. Installation instructions are provided, and they're as basic as they need to be.

This library absolutely supports sub-directories, you just have to configure your server or the library to do so. It doesn't do it magically, why should it? That'd just open up more possibilities for bugs and strange errors. Any attempt at being "magic" would probably make the library more difficult for people to install that are actually doing it correctly.

Documentation on how to implement an autoloader doesn't belong in this library. If you don't know how, then you have to learn elsewhere. This library really goes out of its way to tell people almost too much. Telling people how to setup their Apache/Nginx servers and how to route through a front-controller is a little out of scope, but we try to make it as easy as possible for people to pick up... within reason.

The examples provided expect that the library is installed as per the instructions (and through the most common method), which is via composer.

We've been nice enough to provide people with added instructions in the wiki for people that don't know how to configure a server for a front-controller application and for many other things. Even then, they're unnecessary and out of scope. The README is already huge and the Wiki has decent information. Putting any more in either would just bloat them even further and make it harder to find the important information.

@brettalton
Copy link
Author

Is that a joke? You don't like documenting because that means it's bloat?

That reminds me of the days when I was trying to move from CodeIgniter to Kohana and their documentation would look like this: http://kohanaframework.org/3.0/guide/image/using ... barren.

What's the point of knowing your library can't be used in a folder without modification and not tell people about it? PHP libraries aren't used by robots, they're used by humans, who need good documentation. I'm so sick of seeing good projects refuse to explain what their library is, how it works, why people may or may not want to use it and caveats like using it outside of a root folder structure.

It doesn't take much to explain issues that have arisen by other programmers and by pasting them on a wiki without proper direction isn't any help (e.g. you go from readme -> wiki -> 1 of 5 documents posted ... how would I even know to go there in the first place if I have an issue?).

Did you know the only spot where a supporting website is even documented is in the GitHub project description ("A fast & flexible router
http://chriso.github.io/klein.php/"), but not within the project itself? Easy to miss, espcially since it uses the 'github.io' URL and it looks like you're linking back to the GitHub page of https://github.com/chriso/klein.php.

There is one instance where http://chriso.github.io/klein.php/ is linked, but it's for the API (http://chriso.github.io/klein.php/docs/), which, thanks to phpDocumentor, is incredibly hard to read and I might as well read the source code because it doesn't help me at all.

There does exist the concept of user experience for programmers when using libraries, UX doesn't just apply to the end product. If you think writing a more detailed description means "bloat", then by all means, don't properly document your project.

@chriso
Copy link
Contributor

chriso commented Jan 21, 2014

Calm down. What @Rican7 is trying to say is that the library makes some assumptions about the user's ability to setup a PHP environment with an autoloader and that helping them get to that point is outside the scope of the library. Klein is intended to be installed via composer which provides the autoloading functionality and ensures everything "just works". Writing documentation for integration with various reverse proxies or other exotic setups is outside the scope of the library. @Rican7 puts in a huge effort to upgrade, test and document the library that's entirely free for you to use - should you really be getting annoyed because documentation for your particular setup isn't available at the top of the README?

I disagree that the README should focus on configuration over providing examples. I prefer to see the library in action when I visit a Github page for the first time. As for subdirectories, there is already documentation describing how this works: https://github.com/chriso/klein.php/wiki/Sub-Directory-Installation. We also link to the wiki from the README. How else can we improve this?

@brettalton
Copy link
Author

@Rican7 I have poked around and noted how you rewrote Klein.php 1.2.0 to Klein 2.0.0 and moved it from procedural to OOP and @chriso you being the original author, I didn't mean to offend either of you. I did come off frustrated and I apologize.

I'll adjust the README and do a pull request and we can discuss the changes there.

Then I'll see if there are any other corresponding adjustments that need to be made on your website. Just suggestions and nothing you have to provide by any means.

Klein is a fantastic router and even covers more ground than that. Thanks for posting such a great library online, for free.

@chriso
Copy link
Contributor

chriso commented Jan 22, 2014

@brettalton thanks - suggestions and PRs are always welcome.

@brettalton
Copy link
Author

How do I hook this issue in to #178? It looks like @eimajenthat got a head start.

@eimajenthat
Copy link
Contributor

Well, adding the issue# put a reference in that thread. If you want to improve on my pull request, I guess you could fork my fork, and do another pull request of your own. Where documentation is concerned, I'd say the more the merrier.

@brettalton
Copy link
Author

That's exactly what I'm thinking. Okay, I'll do that.

@eimajenthat
Copy link
Contributor

Oh, and I concur on this:

Klein is a fantastic router and even covers more ground than that. Thanks for posting such a great library online, for free.

I'm using it to take gradually migrate a legacy codebase to using some modern best practices. The simplicity and flexibility of Klein allows me to build new features in a sane way, while preserving the old (less sane) functionality, and gradually refactoring it. With a big, monolithic framework, I'd have a real hard time letting the old stuff coexist. With Klein I just added a route that matches the legacy URL structure, and parse it using the old logic, and then add new routes for my new stuff. Easy peasy.

@tabilluni
Copy link

Hi, I'm in the same process and asked a question over here #179. I have same issue with old (less sane) functionality while gradually refactoring it. Maybe you can help?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants