Yes, but it's not PHP, it's written in C#, but here it goes
var fileContentsAsByteArray = await File.ReadAllBytesAsync(filepath).ConfigureAwait(false);
var fileContents = HttpUtility.UrlEncode(fileContentsAsByteArray);
var body = new Dictionary<string, string>
{
{ "category", request.CategoryId.ToString() },
{ "author", request.AuthorId.ToString() },
{ "title", HttpUtility.UrlEncode(request.Title)},
{ "description", HttpUtility.UrlEncode(request.Description)},
{ $"files[{request.Filename}]", fileContents},
};
if (!string.IsNullOrWhiteSpace(request.Version))
{
body["version"] = HttpUtility.UrlEncode(request.Version);
}
if (!string.IsNullOrWhiteSpace(request.Changelog))
{
body["changelog"] = HttpUtility.UrlEncode(request.Changelog);
}
var bodyString = body.ConvertToQueryString();
var uriPath = fileId.HasValue ? $"index.php?/downloads/files/{fileId.Value}/history" : "index.php?/downloads/files";
var response = await httpClient.PostAsync<UploadFileResult>(
httpClient.BaseAddress,
uriPath,
bodyString,
contentType: "application/x-www-form-urlencoded").ConfigureAwait(false);