opened
bidoubiwa
username_0
### Problem 

Given this [stackoverflow question](https://stackoverflow.com/questions/64342994/how-to-manually-install-dependencies-for-a-php-project) where the user is is stuck because he does not use composer (still too hard for him to grasp), I would like to know if there is a way we can install MeiliSearch without composer? 

I understand the problem lies with the http-client, so the guy in the stackoverflow tried to install it like this: 
```php
include './search/guzzle7/src/Client.php';
include './search/guzzle7/src/Promise.php';
include './search/meilisearchPhp/src/MeiliSearch.php';
include './search/meilisearchPhp/src/Client.php';
```
But it did not work.

### Finding a solution 

Is there a way to make it work? 

Also, alternatively, stripe suggests a [manual installation on their README of their PHP client](https://github.com/stripe/stripe-php#manual-installation). Would we be able to reproduce something like this? 

### Motivations 

PHP is commonly used in the very beginner js-php-mysql stack and I would like for us to be usable by developers of every level.
How do you install MeiliSearch without composer 
issue
created
ppshobi
username_1
I think people who avoid composer should be directed to use composer. Mostly it's because they don't know what it is. the manual installation instructions tend to be error prone over time due to changes in the dependencies
comment
created
bidoubiwa
username_0
I totally agree on my developer side but when you start coding you can not learn everything on the go. You tend to first play around before starting to learn the basics. I would not want a starter to abandon trying out MeiliSearch because we do not offer a simple trying experience. 
Composer is a hard thing to grasp at the start, it can take some time before you feel confident to dive into it.

Now, I'm not sure if this is something hard to do, in which case I might reconsider.
comment
created
ppshobi
username_1
Installing dependency manually is really hard, compared to using composer. For example, it's like avoid using cargo in rust, or downloading npm modules manually and require it without using npm.
comment
created
jdreesen
username_2
You would have to write your own autoloader, I think, which would probably be way harder than understanding how to use composer. There's no way around composer when using PHP nowadays, imho.
comment
created
bidoubiwa
username_0
I looked into [stripe-php](https://github.com/stripe/stripe-php/blob/master/init.php) and they let you do that instead of composer: 

```php
require_once('/path/to/stripe-php/init.php');
```

which seems very simple for a user.


When you look inside the [init.php](https://github.com/stripe/stripe-php/blob/master/init.php) file you have all the dependencies listed:

```php

<?php

// File generated from our OpenAPI spec

// Stripe singleton
require __DIR__ . '/lib/Stripe.php';

// Utilities
require __DIR__ . '/lib/Util/CaseInsensitiveArray.php';
require __DIR__ . '/lib/Util/LoggerInterface.php';
require __DIR__ . '/lib/Util/DefaultLogger.php';
require __DIR__ . '/lib/Util/RandomGenerator.php';
require __DIR__ . '/lib/Util/RequestOptions.php';
require __DIR__ . '/lib/Util/Set.php';
....etc
```

I get this is not a best practice and is maybe not a production-ready code, but the objective is to not gatekeep for beginners. They will mostly not use this in production but in development.

For the `npm` example you made,  we made `no npm` samples for our javascript users which work by copy pasting the following code in a `html` file. Which was asked by some beginners.

```html
<!DOCTYPE html>
<html>
<body>
    Indexes:
    <div id="indexes"></div>
</body>
</html>
<script src="https://cdn.jsdelivr.net/npm/meilisearch@latest/dist/bundles/meilisearch.umd.js"></script>
<script>
  const client = new window.MeiliSearch({
    host: 'http://127.0.0.1:7700',
    apiKey: 'masterKey',
  })
  client.listIndexes().then(res => {
    res.map(index => document.querySelector('#indexes').innerHTML = `<div>${index.name}</div>`)
  })
</script>
```


It's about having the choice without impacting developers' experiences. I don't think having an `init.php` would impact a user that uses `composer`.
comment
created
jdreesen
username_2
It's easier for stripe because they don't have any external composer dependencies. 

But you currently have three `php-http` dependencies, which themselves have a bunch of dependencies, which have dependencies, too, ...

This is why you need an autoloader to properly load all those classes. And the users needs to somehow fetch all those dependencies manually, putting them into the correct folders, ...

All this does composer behind the scenes for you.

---

In the JavaScript world this is easier, because they have the concept of "bundles" which contain everything that's needed in one file and can be included from a CDN easily.

PHP doesn't really have this... except from maybe `.phar` files. Not sure if the maintenance overhead for creating those would be worth it.
comment
created
curquiza
username_3
I don't ask this issue to be a priority, I understand a lot of users are ok with composer, but I want to clarify what we can do so that someone who would be interested in this issue could solve it 👍

I accept we implement a kind of solution/tutorial for non-composer users if:
1. It does not impact the user-experience of composer users
2. It does not bring any inconvenient maintenance

If a big tutorial is needed (more than 5 lines) it will be done in a Wiki section and we will add the link on the README, but the big tutorial will be not present on the README, to respect the point `1`.

If a file like `init.php` is needed, containing all the file names of our SDK, it will be a pain to maintain (and contradicts the point `2`). But, a bash script could be added to the PHP to generate the file. I will add a check in the CI.

As @username_2 said, we still have 3 `php-http` dependencies that makes the work harder.
comment
created
bidoubiwa
username_0
I didn't realize the pain it would be thanks @username_2.

Like @username_3 said if we can find a way to create a bash script that generates a`init.php` that would be great.  If that is not possible, the last solution would be to create a tutorial to use `composer` and meilisearch-php together.
comment
created
shokme
username_4
To show you a little sample of the work required (still not working and vendor lock to guzzle) and I'm far from the end and I will not continue.
I don't see anything on internet able to load guzzle without composer, there was a way in the past of guzzle3 but not the case today.

Don't forget the issue you have link is five year old ! this is huge in dev world.

```php
<?php

include 'meilisearch-php/src/MeiliSearch.php';

# PSR
include 'http-message/src/MessageInterface.php';
include 'http-message/src/RequestInterface.php';
include 'http-message/src/StreamInterface.php';
include 'http-message/src/UriInterface.php';
include 'psr7/src/Utils.php';
include 'psr7/src/Stream.php';
include 'psr7/src/functions.php';
include 'psr7/src/Uri.php';
include 'psr7/src/MessageTrait.php';
include 'psr7/src/Request.php';
include 'http-factory/src/RequestFactoryInterface.php';
include 'http-factory/src/ResponseFactoryInterface.php';
include 'http-factory/src/UriFactoryInterface.php';
include 'http-factory/src/StreamFactoryInterface.php';
include 'http-client/src/ClientInterface.php';

# Discovery
include 'discovery/src/Exception.php';
include 'discovery/src/Exception/NotFoundException.php';
include 'discovery/src/Exception/DiscoveryFailedException.php';
include 'discovery/src/Exception/NoCandidateFoundException.php';
include 'discovery/src/Exception/StrategyUnavailableException.php';
include 'discovery/src/Exception/PuliUnavailableException.php';
include 'discovery/src/Strategy/DiscoveryStrategy.php';
include 'discovery/src/Strategy/PuliBetaStrategy.php';
include 'discovery/src/Strategy/CommonClassesStrategy.php';
include 'discovery/src/Strategy/CommonPsr17ClassesStrategy.php';
include 'discovery/src/ClassDiscovery.php';
include 'discovery/src/Psr18ClientDiscovery.php';
include 'discovery/src/Psr17FactoryDiscovery.php';

# Guzzle
include 'guzzle/src/Exception/GuzzleException.php';
include 'guzzle/src/Exception/TransferException.php';
include 'guzzle/src/Exception/ConnectException.php';
include 'guzzle/src/Handler/EasyHandle.php';
include 'guzzle/src/PrepareBodyMiddleware.php';
include 'promises/src/Create.php';
include 'guzzle/src/Utils.php';
include 'guzzle/src/RequestOptions.php';
include 'guzzle/src/RedirectMiddleware.php';
include 'guzzle/src/Middleware.php';
include 'guzzle/src/Handler/StreamHandler.php';
include 'guzzle/src/Handler/CurlHandler.php';
include 'guzzle/src/Handler/CurlFactoryInterface.php';
include 'guzzle/src/Handler/CurlFactory.php';
include 'guzzle/src/Handler/CurlMultiHandler.php';
include 'guzzle/src/Handler/Proxy.php';
include 'guzzle/src/HandlerStack.php';
include 'guzzle/src/ClientTrait.php';
include 'guzzle/src/ClientInterface.php';
include 'guzzle/src/Client.php';

# Factory

include 'http-factory-guzzle/src/RequestFactory.php';
include 'http-factory-guzzle/src/ResponseFactory.php';
include 'http-factory-guzzle/src/StreamFactory.php';
include 'http-factory-guzzle/src/UriFactory.php';

# Meilisearch

include 'meilisearch-php/src/Contracts/Http.php';
include 'meilisearch-php/src/Contracts/Endpoint.php';
include 'meilisearch-php/src/Delegates/HandlesIndex.php';
include 'meilisearch-php/src/Delegates/HandlesSystem.php';
include 'meilisearch-php/src/Endpoints/Delegates/HandlesDocuments.php';
include 'meilisearch-php/src/Endpoints/Delegates/HandlesSettings.php';
include 'meilisearch-php/src/Endpoints/Delegates/HandlesDumps.php';
include 'meilisearch-php/src/Endpoints/Health.php';
include 'meilisearch-php/src/Endpoints/Version.php';
include 'meilisearch-php/src/Endpoints/Stats.php';
include 'meilisearch-php/src/Endpoints/Keys.php';
include 'meilisearch-php/src/Endpoints/Dumps.php';
include 'meilisearch-php/src/Http/Client.php';
include 'meilisearch-php/src/Client.php';
include 'meilisearch-php/src/Endpoints/Indexes.php';

function run()
{
    $client = new \MeiliSearch\Client('http://localhost:7700');
    $index = $client->getOrCreateIndex('foo');

    var_dump($index);
}

run();
```
comment
created
curquiza
username_3
I know, just a potential help for someone who would be brave enough to try to solve this issue 😉
comment
created
ppshobi
username_1
maybe we can close this?
comment
closed
curquiza
username_3
issue
created
curquiza
username_3
Let's close this then! Feel free to ask a re open if it's needed for someone.
comment