-
Notifications
You must be signed in to change notification settings - Fork 182
Allow manual installation #93
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
Comments
What about creating a Example: <?php
// require this file if you aren't using composer, e.g.
// require_once(dirname(__FILE__) . '/php-redmine-api/lib/autoload.php');
require_once(dirname(__FILE__) . '/Redmine/Api/AbstractApi.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Attachment.php');
require_once(dirname(__FILE__) . '/Redmine/Api/CustomField.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Group.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Issue.php');
require_once(dirname(__FILE__) . '/Redmine/Api/IssueCategory.php');
require_once(dirname(__FILE__) . '/Redmine/Api/IssuePriority.php');
require_once(dirname(__FILE__) . '/Redmine/Api/IssueRelation.php');
require_once(dirname(__FILE__) . '/Redmine/Api/IssueStatus.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Membership.php');
require_once(dirname(__FILE__) . '/Redmine/Api/News.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Project.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Query.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Role.php');
require_once(dirname(__FILE__) . '/Redmine/Api/SimpleXMLElement.php');
require_once(dirname(__FILE__) . '/Redmine/Api/TimeEntry.php');
require_once(dirname(__FILE__) . '/Redmine/Api/TimeEntryActivity.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Tracker.php');
require_once(dirname(__FILE__) . '/Redmine/Api/User.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Version.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Wiki.php');
require_once(dirname(__FILE__) . '/Redmine/Client.php'); |
@mjorlitzky i'm with @Art4 : could you give his solution a try? |
That'll work for me personally, but won't be so nice for our end users if I package it for Gentoo.
Given those downsides, I'd probably opt to just patch the source files like I've done above. I would still have to update the patch every once in a while, but at least it wouldn't bother anyone else. Of course I would rather do nothing, though =) |
Perhaps too simple-minded, but: Can't you just copy the lib-folder wherever you want it in your project-dir and than, in your project, register the namespace \Redmine to the corresponding dir? |
First of all, copy/pasting code shouldn't be considered a solution to anything =) The problems it causes are familiar-enough that I don't need to repeat them here, and they're the reason I'd like to be able to create a distro package for the library and install it once globally. None of the local fixes address the real problem (please excuse the pejorative): the library appears broken for end-users who aren't me. I can't install and maintain a mangled version that requires secret voodoo for our web developers at work, and I can't ship the same to our end-users on Gentoo either. But as is, it just doesn't work. For example, It's like if you had a |
@orlitzky if author add You can simple create bootstrap file or use composer in any system that you want. But composer you will have a lot of benefits.
Yes. you don`t But remember there are a lot of contributors to make cat work in all systems *nix. This is other story and this is hard to create php project optimized for web and for command line scripts in any platform. |
So, in your entire project, you don't use ANY classloader (to whom you can register the namespace Redmine, which effectively gives you the required require)? There is NO chance you can add the three lines from http://php.net/manual/de/language.oop5.autoload.php to some script that uses this api? |
@funivan Have you actually tried it? Autoload is many times slower than just adding the necessary PHP is not a clever language. When all is said and done, the interpreter sees a big linear blob of code. If the It's not hard to create PHP scripts that work on the web and on the command-line, and PHP is no different than C or any other language. If you do things right, they work. If you don't, they don't. Right now the library crashes out-of-the-box both on the web and the command line. With the proper |
@osroot25 You're looking at this all wrong. I would like to be able to create a distribution package for php-redmine-api that works out of the box. I don't know who's going to install it, and I can't SSH into their homes and add any number of lines of code to whatever projects they're working on. I am using this for a personal project, and I am able to work around the problem by patching the source or registering an autoloader or whatever. But I'd like to have the library installed globally and use the package manager to make sure that no one e.g. uninstalls php-redmine-api. To do that, I need to create a package for php-redmine-api. To do that, I need to kill the dependency on composer. |
@orlitzky )) Yes i try it. If you use multiple libraries in project autoloader is best solution. If you use only 1 library and you require all classes of it - possible require is better. In general: current installation method is very good. |
This is true not only when you "load all your classes," but whenever autoload will load the same number of classes as the manual In your own projects, you don't need to worry either way: I've added the |
How about add the The downside is that we have to think about the autoload.php if a new file is added. Or we add a simplified autoloader in |
@Art4 Is the goal really to keep a few
It would still be better than the current situation, though, where I have no way to generate |
Sure, but this is the same with your solution. What's the different between
Hmm, I'm not sure. If you call
I think it will be a greater mess to keep the dependency for each file through And this is a simple untested autoloader: <?php
// lib/autoload.php
spl_autoload_register(function ($class) {
if (file_exists(dirname(__FILE__) . 'Redmine/Api/' . $class . '.php'))
{
require_once dirname(__FILE__) . 'Redmine/Api/' . $class . '.php';
}
if (file_exists(dirname(__FILE__) . 'Redmine/' . $class . '.php'))
{
require_once dirname(__FILE__) . 'Redmine/' . $class . '.php';
}
});
I don't get this point, sorry. :-/ |
I guess if the autoloader is capable of loading the require('lib/autoload.php');
require('lib/Redmine/Client.php'); About the speed, I could try to convince you from first principles that the sky is not pink, but I agree a benchmark is in order. The stupidest thing that could possibly work ( <?php
//require('lib/php-redmine-api/lib/autoload.php');
require('lib/php-redmine-api/lib/Redmine/Client.php');
$start_time = microtime(TRUE);
$c = new Redmine\Client("foo","bar");
$end_time = microtime(TRUE);
echo $end_time - $start_time;
?> At the top, there are two
You don't have to remember anything. If you add code to e.g.
You need to account for the <?php
// lib/autoload.php
spl_autoload_register(function ($class) {
$class = str_replace('\\', '/', $class);
$path = dirname(__FILE__) . '/' . $class . '.php';
if (file_exists($path)){
require_once($path);
}
$path = dirname(__FILE__) . '/' . $class . '.php';
if (file_exists($path)) {
require_once($path);
}
});
?>
I thought you were suggesting generating an I think keeping track of the includes is better for one's long-term sanity, but I would be grateful for this solution as well. |
I should also mention that |
I'm surprised about the benchmark results. I have assumed, that the result would differ for about 50%. The require() calls are the same but in different files. Maybe we should remove the
Are you sure you don't mixed up the code? The benchmark.php looks to me it used the same code. If I'll have time I will test it today. benchmark.php should look like this: <?php
//require('lib/php-redmine-api_art4/lib/autoload.php');
require('lib/php-redmine-api_orlitzky/lib/Redmine/Client.php');
$start_time = microtime(TRUE);
$c = new Redmine\Client("foo","bar");
$end_time = microtime(TRUE);
echo $end_time - $start_time;
?>
But this is not how this library worked till today. All developers who have not chanced the code are using the library with composer. If we forget a I recommend to keep the files clear of the |
The difference is much bigger than it looks. If you have two relatively close numbers, like say Both methods are including the same files, eventually, but autoload has to register a callback, run the callback every time a class is instantiated, check if a file exists, check if it's been required already, etc. The benchmark doesn't even use any of the features in
Yes, I was simply renaming the php-redmine-api directory. |
It occurs to me that, even if you use composer to install the library, nobody is going to |
@orlitzky I have benchmark all three possibilities. 1. my list of 1. require listin <?php
// require this file if you aren't using composer, e.g.
// require_once(dirname(__FILE__) . '/php-redmine-api/lib/autoload.php');
require_once(dirname(__FILE__) . '/Redmine/Api/AbstractApi.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Attachment.php');
require_once(dirname(__FILE__) . '/Redmine/Api/CustomField.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Group.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Issue.php');
require_once(dirname(__FILE__) . '/Redmine/Api/IssueCategory.php');
require_once(dirname(__FILE__) . '/Redmine/Api/IssuePriority.php');
require_once(dirname(__FILE__) . '/Redmine/Api/IssueRelation.php');
require_once(dirname(__FILE__) . '/Redmine/Api/IssueStatus.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Membership.php');
require_once(dirname(__FILE__) . '/Redmine/Api/News.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Project.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Query.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Role.php');
require_once(dirname(__FILE__) . '/Redmine/Api/SimpleXMLElement.php');
require_once(dirname(__FILE__) . '/Redmine/Api/TimeEntry.php');
require_once(dirname(__FILE__) . '/Redmine/Api/TimeEntryActivity.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Tracker.php');
require_once(dirname(__FILE__) . '/Redmine/Api/User.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Version.php');
require_once(dirname(__FILE__) . '/Redmine/Api/Wiki.php');
require_once(dirname(__FILE__) . '/Redmine/Client.php'); 2. require() on top of filesI have made the changes from your first post. 3. simple autoloaderin lib/autoload.php <?php
spl_autoload_register(function ($class) {
$class = str_replace('\\', '/', $class);
$path = dirname(__FILE__) . '/' . $class . '.php';
if (file_exists($path)){
require_once($path);
}
}); benchmark.phpI have used this file to benchmark all three possibilities. The results are micro seconds. <?php
//require('php-redmine-api_art4/lib/autoload.php'); // 1
//require('php-redmine-api_orlitzky/lib/Redmine/Client.php'); // 2
require('php-redmine-api_autoload/lib/autoload.php'); // 3
$start_time = microtime(true);
$c = new Redmine\Client("foo","bar");
$end_time = microtime(true);
echo sprintf('%.10f', $end_time - $start_time) * 100000 . " \n"; ResultsResults are in microseconds.
tomorrow more... |
Thanks for taking the time to do that. Your solution and mine will benchmark roughly the same because right now If we add ~20 new files under
...
then the two benchmarks would begin to diverge. Ostensibly the Note: I don't actually care about the performance, so that isn't a big deal, but it's part of the reason why I consider require-at-the-top to be a better design. I only started talking benchmarks because it was claimed that autoload was faster and that was given as a reason to leave things alone. |
I've done this benchmark because I thought you benchmarked our first solutions (1 and 2) and I was surprised your solution 2 was 15x faster than mine. 😄 But at all we are talking about microseconds. To sum everything up:
I think, we discussed everything. @kbsali what do you think? |
@Art4 thanks a lot for the clear benchmark! 👍 As far as I'm concerned, Solution 1 and 3 are the only valid ones; and given that solution 3 appears to be much slower than the 2 others, I would go in favor @Art4 's! Feel free to create a PR to get this in. Again, thank you all for trying to getting around all this! |
Hello, I'd like to be able to install the library manually (i.e. without composer). Ultimately my goal is to package it for Gentoo, so that users can install it using our package manager, portage.
I've hit a problem though: unlike the other language install tools (rubygems, cabal, etc.), composer encourages you to use its autoload.php file instead of keeping track of includes at the top of each file. This sounds nice at first, until you try to install a library without composer -- if I use another package manager to install the library instead of composer, it doesn't work! All the include()s are missing.
Would it be possible to add the includes to the source files that need them? This should make it possible to install the library manually, and will also have the nice side effect of making the source easier to hack on without going through a composer install.
I've made the following changes locally and they were enough to get me started:
The text was updated successfully, but these errors were encountered: