// index.php
function download(string $filePath): void
{
if (!headers_sent()) {
ob_end_clean();
}
if (!file_exists($filePath)) {
throw new InvalidArgumentException('File not exists');
}
$filesize = filesize($filePath);
$fileObject = new SplFileObject($filePath, 'rb');
header('content-type: audio/mpeg');
$range = 0;
if (isset($_SERVER['HTTP_RANGE'])) {
$range = $_SERVER['HTTP_RANGE'];
$range = str_replace('bytes=', '', $range);
[$range] = explode('-', $range);
if (!empty($range)) {
$fileObject->fseek($range);
}
}
if ($range) {
header($_SERVER['SERVER_PROTOCOL'] . ' 206 Partial Content');
} else {
header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK');
}
header('Accept-Ranges: bytes');
header('Content-Description: inline; File Transfer');
header('Content-Disposition: attachment; filename="' . basename($fileObject->getBasename()) . '";', false);
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . ($filesize - $range));
if ($range) {
header('Content-Range: bytes ' . $range . '-' . ($filesize - 1) . '/' . $filesize);
}
header('Connection: close');
$speed = 100;
while (!$fileObject->eof() && connection_status() === 0) {
echo $fileObject->fread(1024 * $speed);
flush();
#sleep(1); // разкоментирование приведет к ограничению скорости в 100 kb
}
}
download('./1.mp3');
<span class="green"><audio controls><source src="http://localhost/dnl/index.php"></audio></span>
Request URL: http://localhost/dnl/index.php
Request Method: GET
Status Code: 206 Partial Content
Remote Address: 127.0.0.1:80
Referrer Policy: strict-origin-when-cross-origin
Accept-Ranges: bytes
Connection: close
Content-Description: inline; File Transfer
Content-Disposition: attachment; filename="1.mp3";
Content-Length: 168977156
Content-Range: bytes 2097152-171074307/171074308
Content-Transfer-Encoding: binary
Content-Type: audio/mpeg
Date: Sat, 15 Apr 2023 19:03:29 GMT
Server: Apache
X-Content-Type-Options: nosniff
Accept: */*
Accept-Encoding: identity;q=1, *;q=0
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,nb;q=0.6
Connection: keep-alive
DNT: 1
Host: localhost
Range: bytes=2097152-
Referer: http://localhost/dnl/index.html
sec-ch-ua: "Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: video
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
CURLOPT_HEADERFUNCTION
A callback accepting two parameters. The first is the cURL resource, the second is a string with the header data to be written. The header data must be written by this callback. Return the number of bytes written.
CURLOPT_READFUNCTION
A callback accepting three parameters. The first is the cURL resource, the second is a stream resource provided to cURL through the option CURLOPT_INFILE, and the third is the maximum amount of data to be read. The callback must return a string with a length equal or smaller than the amount of data requested, typically by reading it from the passed stream resource. It should return an empty string to signal EOF.
$accesstoken = 'secret';
//$data = json_decode($data, true);
$data = ['folder' => './test', 'Name' => '11.json'];
$taskId = 1;
$file = Cb::FILES_DIR . '/' . $taskId . '.' . $data['folder'] . '/' . $data['Name'];
$headers = [];
//$headers[] = 'Content-length: ' . filesize($file);
$headers[] = 'Content-type: application/json';
$headers[] = 'Authorization: Basic ' . $accesstoken;
$headers[] = 'Transfer-Encoding: chunked';
$stream = fopen($file, 'rb');
$log = fopen("curl.txt", 'a');
$url = 'https://portal5test.cbr.ru/back/rapi2/messages....';
$ch = curl_init($url);
//curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_UPLOAD, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_INFILE, $stream);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($file));
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, $log);
curl_setopt($ch, CURLOPT_READFUNCTION, static function ($ch, $stream, $length) {
return fgets($stream, $length);
});
$result = curl_exec($ch);
curl_close($ch);
$text = 'Message text'; // Текст сообщения
$subject = 'Message subject'; // Тема письма
$email = 'test@mail.ru'; // Адрес электронной почты
$body = '';
// Забираем имя файла и содержимое из файлового поля формы
$fileName = $_FILES['file']['name'];
$fileStream = file_get_contents($_FILES['file']['tmp_name']);
// Специальный сепаратор письма, разделитель частей
$bound = '_=_Multipart_Boundary_' . substr(md5(uniqid('', true)), 0, 8);
// Заголовок письма
$header = 'Content-Type: multipart/mixed; boundary="' . $bound . '"' . PHP_EOL . 'X-Mailer: PHP' . PHP_EOL . 'Reply-To: No reply' . PHP_EOL;
// Секция текстовой части
$body .= '--' . $bound . PHP_EOL .
'Content-Type: text/plain; charset="UTF-8"' . PHP_EOL .
'Content-Disposition: inline' . PHP_EOL .
'Content-Transfer-Encoding: base64' . PHP_EOL . PHP_EOL .
chunk_split(base64_encode($text)) . PHP_EOL;
// Секция файловой части
$body .= PHP_EOL . '--' . $bound . PHP_EOL .
'Content-Type: application/octet-stream; name="' . $fileName . '"' . PHP_EOL .
'Content-Disposition: attachment;' . PHP_EOL .
' filename="' . $fileName . '"' . PHP_EOL .
'Content-Transfer-Encoding: base64' . PHP_EOL . PHP_EOL . chunk_split(base64_encode($fileStream));
// Конец
$body .= '--' . $bound . '--';
mail(
$email,
'=?UTF-8?B?' . base64_encode($subject) . '?=',
$body,
'MIME-Version: 1.0' . PHP_EOL . $header
);
поняно ответили, особенно для человека, который в php далекий
<?php
$builder = new Builder();
$query = $builder
->table('test')
->select(['*'])
->where(['field1', 'in', [1,2,3]], ['field2', 'like', '%ab%'])
->limit(10, 20)
->get();
$placeholders = $builder->getPlaceholders();
$result = $pdo->prepare($query)->execute($placeholders);
/* фетч результата */
<?php
namespace Compolomus\Builder;
use RuntimeException;
final class Builder
{
private ?string $table = null;
private array $where = [];
private array $columns = ['*'];
private array $placeholders = [];
private ?string $queryType = null;
public function __construct(?string $table = null)
{
if (!is_null($table)) {
$this->table = $table;
}
}
public function table(string $table): Builder
{
$this->table = $table;
return $this;
}
public function count(): Builder
{
$this->queryType = 'select count(*)';
return $this;
}
public function select(?array $columns = null): Builder
{
if (!is_null($columns)) {
$this->columns = $columns;
}
return $this;
}
public function limit(int $limit, int $offset = 0): Builder
{
/*
тут собираем строку с лимит и куда нибудь сохраняем
*/
return $this;
}
public function where(array $conditions, string $type = 'and'): Builder
{
foreach ($conditions as [$field, $condition, $value]) {
/* тут собираем строку из поля, значения и типа */
/* вместо значения подставляем плейсхолдер ? для подготовленных выражений */
$this->placeholders[] = $value;
}
/* куда то сохраняем собранную строку,
по типу собираем массив с типом обьединения,
тут на самом деле всё сложно,
возможно проще будет создать Where класс и отдать туда обработку
*/
return $this;
}
/**
* @throws RuntimeException
*/
public function get(): string
{
if (is_null($this->queryType)) {
throw new RuntimeException('Undefined query type');
}
$query = strtoupper($this->queryType);
/* тут собираем весь запрос из кусочков */
return $query;
}
public function getPlaceholders(): array
{
$placeholders = $this->placeholders;
$this->placeholders = [];
/* обязательно обнуляем, возможно и весь билдер для следующего запроса */
return $placeholders;
}
}
class MyJson
{
private array $data;
public function __construct(array $array)
{
$this->data = $array;
}
public function __call(string $name, array $arguments)
{
$action = substr($name, 0, 3);
$property = strtolower(substr($name, 3));
switch ($action) {
case 'get':
return $this->data[$property ] ?? null;
case 'set':
$this->data[$property] = $arguments[0];
break;
}
}
public function __set(string $name, $value)
{
$this->data[$name] = $value;
}
public function __get(string $name)
{
return array_key_exists($name, $this->data)) ? $this->data[$name] : null;
}
public function __isset($name): bool
{
return isset($this->data[$name]);
}
public function __unset($name): void
{
unset($this->data[$name]);
}
}
$json = new MyJson(json_decode($json, true));
echo $json->name;
$json->name = 'test';
echo $json->getName();
$json->setName('test2');
echo $json->name;
RemoveHandler .php .phtml .php3 .php4 .php5 .php6 .phps .cgi .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .py
AddType application/x-httpd-php-source .php .phtml .php3 .php4 .php5 .php6 .phps .cgi .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .py
php_flag engine 0
<Files *.php>
Deny from all
</Files>
// исходник маски
$mask = new Imagick($_SERVER['DOCUMENT_ROOT'] . '/mask.png');
// меняем прозрачный цвет на оранжевый и черный на прозрачный
$mask->opaquePaintImage('transparent', 'orange', 10, false, Imagick::CHANNEL_DEFAULT);
$mask->opaquePaintImage('black', 'transparent', 10, false, Imagick::CHANNEL_DEFAULT);
//$mask->writeImage($_SERVER['DOCUMENT_ROOT'] . '/prepare-mask.png');
// исходник изображения
$source = new Imagick($_SERVER['DOCUMENT_ROOT'] . '/image.jpeg');
// накладываем маску на изображение
$mask->compositeImage($source, Imagick::COMPOSITE_DSTOVER, 0, 0); //COMPOSITE_DSTATOP
//$mask->writeImage($_SERVER['DOCUMENT_ROOT'] . '/composite.png');
// меняем оранжевый цвет на прозрачный
$mask->opaquePaintImage('orange', 'transparent', 10, false, Imagick::CHANNEL_DEFAULT);
$mask->setImageFormat('png');
//$mask->writeImage($_SERVER['DOCUMENT_ROOT'] . '/result.png');
header('Content-type: image/png');
echo $mask;