Ответы пользователя по тегу PHP
  • Как реализовать эффект двоения?

    Ninazu
    @Ninazu
    Судя по тому что нужно вам необходимо проделать с копируемыми картинками три вещи
    1. Задать им уровень прозрачности разный (от меньшего к большему)
    2. Применить blur (по той же схеме что и с прозрачностью)
    3. Разрезать по диагонали и сместить треугольники
    Ответ написан
  • Где найти примеры хорошего кода php?

    Ninazu
    @Ninazu
    Начнем с того. С какими вы фреймворками работали?)

    Может нужен просто легкий фрейм?
    https://www.slimframework.com/

    Ну а если хочется БДСМ
    https://github.com/leocavalcante/siler

    Хотя я бы рекомендовал остановиться на Symfony
    Ответ написан
    Комментировать
  • Как заменить белый фон на прозрачный с помощью PHP (GD)?

    Ninazu
    @Ninazu
    imagecolorat - получить цвет пикселя
    imagesetpixel - выставить цвет пикселя
    imagecolorallocatealpha - чтоб создать пустой цвет
    imagealphablending - выставить режим смешивания
    imagesavealpha - сохранить с прозрачностью
    Ответ написан
    Комментировать
  • Почему перестал открываться index.php на open server?

    Ninazu
    @Ninazu
    1. По какому пути вы пытаетесь попасть на страницу?
    2. Существует ли файл all/home.php?
    3. Что в .htaccess?
    Ответ написан
  • Можно ли исправить эту очень полезную функцию PHP?

    Ninazu
    @Ninazu
    Если уже переписываете, то переписывайте нормально. Избавляйтесь от глобального массива $CONF, рекурсии и функций без неймспейсов. Также у вас функция как записывает так и читает значения, что немного выносит мозг. Также считаю что исключению там не место, лучше заменить на значение по умолчанию

    class Config {
    
    	protected static array $register = [];
    
    	public static function get(string $name, $default = null) {
    		$keys = explode('.', $name);
    
    		$pointer = self::$register;
    
    		foreach ($keys as $key) {
    			if (!array_key_exists($key, $pointer)) {
    				/*Если ключа нет, выставить его*/
    				//self::set($name, $default);
    
    				/*Бросить исключение*/
    				//throw new Exception("No such key: {$name}");
    
    				/*Вернуть значение по умолчанию*/
    				return $default;
    			}
    
    			$pointer = &$pointer[$key];
    		}
    
    		return $pointer;
    	}
    
    	public static function set(string $name, $value = null) {
    		$arr = &self::$register;
    		$keys = explode('.', $name);
    
    		foreach ($keys as $key) {
    			$arr = &$arr[$key];
    		}
    
    		if (is_array($arr) && is_array($value)) {
    			$arr = array_replace_recursive($arr, $value);
    		} else {
    			$arr = $value;
    		}
    	}
    
    	public static function getTree() {
    		return self::$register;
    	}
    }
    
    Config::set("config", [
    	"name" => "test",
    ]);
    print_r(Config::get("config"));
    echo "(config)\n\n";
    
    Config::set("config.class.name", "A");
    print_r(Config::get("config.class.name"));
    echo "\n(config.class.name)\n\n";
    
    Config::set("config", [
    	"class" => [
    		"test" => "B",
    	],
    ]);
    print_r(Config::get("config.class"));
    echo "\n(config.class)\n\n";
    
    Config::set("config.class", null);
    print_r(Config::get("config.class"));
    echo "\n(config.class)\n\n";
    
    print_r(Config::get("config.fake.key.without.value", "UNDEFINED"));
    echo "\n(config.fake.key.without.value)\n\n";
    
    Config::set("config.nullable", null);
    print_r(Config::get("config.nullable", "NULL"));
    echo "\n(config.nullable)\n\n";
    
    print_r(Config::getTree());
    echo "\n(all)\n";


    Работает в PHP7.4
    Ответ написан
    6 комментариев
  • Как зашифровать АПИ токен на стороне клиента?

    Ninazu
    @Ninazu
    Ничего шифровать не нужно. Алгоритм такой
    1. Берете https://github.com/Valve/fingerprintjs2
    2. Отправляете результат его работы c каждым запросом
    3. Авторизируетесь и получаете токен который на сервере привязан к fingerprint и IP
    4. При получении запроса с токеном и fingerprint, проверяете наличие токена в своем хранилище, и соответсвие токена IP и fingerprint которые пришли с клиента
    5. Если не прошла проверка, заставляйте авторизироваться снова.

    P.S. IP часто динамический. Так что учитывайте это. Например много людей используют мобильный интернет. Плюс нужно понимать что может быть несколько устройств. Пользователь может зайти с планшета, телефона и ПК
    Ответ написан
    2 комментария
  • Зависит ли класс А от Б в данном случае?

    Ninazu
    @Ninazu
    Зависит! Чтоб не зависел, используйте интерфейсы

    interface D {
    
    	public function execute();
    }
    
    class B implements D {
    
    	public function execute() {
    		return "This is B";
    	}
    }
    
    class C implements D {
    
    	public function execute() {
    		return "This is C";
    	}
    }
    
    class A {
    
    	public function __construct(D $class = null) {
    		if (!is_null($class)) {
    			echo $class->execute();
    		}
    	}
    }
    
    new A();
    new A(new B());
    new A(new C());
    Ответ написан
    2 комментария
  • Как реализовать облачное хранилище?

    Ninazu
    @Ninazu
    Начните с абстракции, интерфейсов и балансеров)) Ваша система не должна вообще ничего знать про то, где что хранится. Для начала это должен быть балансер, который в самом простом примере ведёт на локальный компьютер. В будущем будет вести на удалённый сервер, а еще позже на группу серверов распределяя контент по ним.

    5696459148099584.png
    Ответ написан
    Комментировать
  • Как настроить поддержку PUT- и DELETE-запросов на локальном сервере Xampp?

    Ninazu
    @Ninazu
    REST - дно) Не слушайте хипстеров. И забудьте про него.

    Ну а вообще очень похоже на то что ноги с CORS идут.
    Стандарт Cross-Origin Resource Sharing работает с помощью добавления новых HTTP-заголовков, которые позволяют серверам описывать набор источников, которым разрешено читать информацию, запрашиваемую web-браузером. В частности, для методов HTTP-запросов, которые могут привести к побочным эффектам над данными сервера (в частности, для HTTP методов, отличных от GET или для POST запросов, использующих определнные MIME-типы), спецификация требует, чтобы браузеры "предпроверяли" запрос, запрашивая поддерживающие методы с сервера с помощью метода HTTP-запроса OPTIONS и затем, поверх "подтверждения" с сервера, отсылали фактический запрос с фактическим методом HTTP-запроса
    Ответ написан
  • Как разобрать код: str_rev(md5("base64(qwerty)"))?

    Ninazu
    @Ninazu
    5deb6341d24a0674259660.png

    Всё равно следующий этап вы не пройдёте)

    5deb8e14156f0162125355.png
    Ответ написан
  • Возвращает NULL в $_POST запросе,когда есть капча,и выбрано 2 файла на загрузку,почему?

    Ninazu
    @Ninazu
    Рекомендую начать с работающего примера, и потом усложнять его капчами и прочей логикой

    <?php
    if ($_POST) {
    	die(json_encode([$_POST, $_FILES]));
    }
    ?>
    
    <form enctype="multipart/form-data" method="POST">
    	<input type="text" name="name" required></br>
    	<input type="file" name="file[]" multiple style="margin-bottom: 5px;">
    	<input type="submit" name="gsubmit" value="Отправить"></br>
    </form>
    <script>
    	document.querySelector("form").addEventListener("submit", function(e) {
    		let form = e.target;
    		e.preventDefault();
    		e.stopImmediatePropagation();
    		let xhr = new XMLHttpRequest();
    
    		xhr.open(form.method, form.action);
    		xhr.onreadystatechange = function(result) {
    			if (xhr.readyState === 4 && xhr.status === 200) {
    				let responseData = JSON.parse(xhr.responseText);
    				console.log(responseData);
    			}
    		};
    
    		xhr.send(new FormData(form));
    	}, true);
    </script>
    Ответ написан
    2 комментария
  • Можно ли сделать бота для нажатия на кнопки?

    Ninazu
    @Ninazu
    1. Там за каждое нажатие кнопки без капчи, нужно заплатить 1 reward point
    2. Капчу можно решить с помощью сервисов вроде rucaptcha

    package main
    
    import (
    	"context"
    	"fmt"
    	"github.com/chromedp/cdproto/network"
    	"github.com/chromedp/chromedp"
    	"log"
    	"time"
    )
    
    var (
    	dir = "ПАПКА_КУДА_СОХРАНЯЮТСЯ_COOKIE"
    	domain = "https://freebitco.in/"
    	wait   = 3
    	login = true //Выставить в false, после авторизации
    )
    
    func main() {
    	opts := append(chromedp.DefaultExecAllocatorOptions[:],
    		chromedp.DisableGPU,
    		chromedp.NoDefaultBrowserCheck,
    		chromedp.Flag("enable-automation", true),
    		chromedp.Flag("use-mock-keychain", true),
    		chromedp.Flag("headless", !login),
    		chromedp.Flag("no-first-run", true),
    		chromedp.Flag("no-sandbox", true),
    		chromedp.Flag("ignore-certificate-errors", true),
    		chromedp.Flag("user-data-dir", dir),
    	)
    
    	allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
    	defer cancel()
    
    	taskCtx, cancel := chromedp.NewContext(allocCtx, chromedp.WithLogf(log.Printf))
    	defer cancel()
    
    	if err := chromedp.Run(taskCtx); err != nil {
    		panic(err)
    	}
    
    	var reward string
    
    	err := chromedp.Run(taskCtx,
    		network.Enable(),
    		chromedp.Navigate(domain),
    		chromedp.Action(chromedp.ActionFunc(func(ctx context.Context) error {
    			time.Sleep(time.Duration(wait) * time.Second)
    
    			return nil
    		})),
    		chromedp.WaitVisible(`#play_without_captchas_button`),
    		chromedp.Click(`#play_without_captchas_button`, chromedp.NodeVisible),
    		chromedp.Action(chromedp.ActionFunc(func(ctx context.Context) error {
    			time.Sleep(time.Duration(wait) * time.Second)
    
    			return nil
    		})),
    		chromedp.Click(`#free_play_form_button`, chromedp.NodeVisible),
    		chromedp.Action(chromedp.ActionFunc(func(ctx context.Context) error {
    			time.Sleep(time.Duration(wait) * time.Second)
    
    			return nil
    		})),
    		chromedp.TextContent(`#winnings`, &reward),
    	)
    
    	if err != nil {
    		panic(err)
    	}
    
    	fmt.Println(reward)
    }
    Ответ написан
  • Как распарсить массив c частичным совпадением ключей?

    Ninazu
    @Ninazu
    Если неизвестны возможные ключи и количество индексов, а вывод нужно нормализировать

    <?php
    $array = [
    	'text_1' => ['I am so clever that sometimes I do not underst'],
    	//'text_2' => ['It is better to be hated for what you are than f.'],
    	'text_3' => ['Whenever you find yourself on the .'],
    	'text_4' => ['Whenever you find yourself on the side of the majority.'],
    	'title_1' => ['Responsive design'],
    	'title_2' => ['Web development'],
    	'title_3' => ['Customer support'],
    	'title_4' => ['images included'],
    	'title_text_1' => ['Unexpected'], //Может и такое быть
    	'_edit_lock' => ['1570606503:1'],
    	'_thumbnail_id' => ['59'],
    	'_edit_last' => ['1'],
    	'single_image_1' => ['94'],
    	'single_image_2' => ['91'],
    	'single_image_3' => ['92'],
    	'single_image_4' => ['93'],
    ];
    
    $prefixes = [];
    $maxIndex = 0;
    
    foreach (array_keys($array) as $key) {
    	$parts = explode('_', $key);
    	$index = array_pop($parts);
    
    	if (!is_numeric($index)) {
    		continue;
    	}
    
    	$prefixes[implode('_', $parts)] = null;
    
    	if ($index > $maxIndex) {
    		$maxIndex = $index;
    	}
    }
    
    $output = [];
    $prefixes = array_keys($prefixes);
    
    for ($index = 1; $index <= $maxIndex; $index++) {
    	$row = [];
    
    	foreach ($prefixes as $prefix) {
    		$key = "{$prefix}_{$index}";
    		$row[$key] = @$array[$key];
    	}
    
    	$output[] = $row;
    }
    
    var_dump($output);


    sandbox.onlinephpfunctions.com/code/1fd759f48a4653...
    Ответ написан
    Комментировать
  • Как осуществить перенаправление запроса с одного сайта на другой с выводом результата на первый?

    Ninazu
    @Ninazu
    В htaccess site1 добавить
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^site1.com
    RewriteRule ^(.*) http://site2.com/$1 [P]


    P.S. Если не взлетело, и падает с 500-й ошибкой. Проверить также что включены модули mod_rewrite, mod_proxy и на всякий случай mod_proxy_http
    Ответ написан
    Комментировать
  • Как составить регулярку?

    Ninazu
    @Ninazu
    <?php
      
    $regExp = "/(\.(\w+){1})|(^\w+$)/";
    
    
    $tests = [
        "web.test1.pages.page",
        "web.test2",
        "web.test3.yes",
        "test4",
    ];
    
    foreach($tests as $test){
        if(preg_match($regExp, $test, $matches)){
            var_dump(end($matches));
        }
    }
    Ответ написан
  • Какие принципы SOLID здесь нарушены?

    Ninazu
    @Ninazu Автор вопроса
    Сделал через Visitor, по моему получилось неплохо.

    <?php
    
    interface IVisitor {
    
    	public function getResult();
    
    	public function visit(IShape $element): void;
    }
    
    interface IShape {
    
    	public function accept(IVisitor $visitor): void;
    }
    
    interface IArea extends IShape {
    
    	public function getArea(): float;
    }
    
    interface IFillColor extends IShape {
    
    	public function setFillColor(string $rgb);
    
    	public function getFillColor(): int;
    }
    
    trait TFillColor {
    
    	protected $fillColor = 0;
    
    	public function getFillColor(): int {
    		return $this->fillColor;
    	}
    
    	public function setFillColor(string $rgb) {
    		$this->fillColor = (int)hexdec($rgb);
    	}
    }
    
    class Line implements IArea {
    
    	protected $length;
    
    	public function __construct(float $length) {
    		$this->length = $length;
    	}
    
    	public function getArea(): float {
    		return $this->length;
    	}
    
    	public function accept(IVisitor $visitor): void {
    		$visitor->visit($this);
    	}
    }
    
    class Rectangle implements IShape, IFillColor {
    
    	use TFillColor;
    
    	protected $width;
    
    	protected $height;
    
    	public function __construct(float $width, float $height) {
    		$this->width = $width;
    		$this->height = $height;
    	}
    
    	public function getArea(): float {
    		return $this->width * $this->height;
    	}
    
    	public function accept(IVisitor $visitor): void {
    		$visitor->visit($this);
    	}
    }
    
    class Box {
    
    	/**@var IShape[] $shapes */
    	protected $shapes = [];
    
    	public function addShape(IShape $shape): self {
    		$this->shapes[] = $shape;
    
    		return $this;
    	}
    
    	public function executeVisitor(IVisitor $visitor) {
    		foreach ($this->shapes as $shape) {
    			$shape->accept($visitor);
    		}
    
    		return $visitor->getResult();
    	}
    }
    
    class TotalAreaWithColor implements IVisitor {
    
    	protected $total = 0;
    
    	protected $color;
    
    	public function __construct(int $color) {
    		$this->color = $color;
    	}
    
    	public function visit(IShape $element): void {
    		if ($element instanceof IFillColor && $element->getFillColor() === $this->color) {
    			$this->total += $element->getArea();
    		}
    	}
    
    	public function getResult() {
    		return $this->total;
    	}
    }
    
    $rect  = new Rectangle(4, 10);
    $rect->setFillColor("FF0000");
    
    $line = new Line(10);
    
    echo (new Box())
    	->addShape($rect)
    	->addShape($line)
    	->executeVisitor(new TotalAreaWithColor(hexdec("FF0000")));
    Ответ написан
  • Как отсортировать такой массив?

    Ninazu
    @Ninazu
    Если уровней вложенности только два. То можно и без рекурсии

    $categories = [];
    
    foreach($list as $row){
        if ($row['parent_id'] == 0) {
            continue;
        }
    
        $categories[$row['parent_id']][] = $row['name'];
    }
    
    foreach($categories as $names){  
         echo "<ul>";
         foreach($names as $name){
                  echo "<li>{$name}</li>";
         }
         echo "</ul>";
    }
    Ответ написан
    Комментировать
  • Как передать ошибку пользователю из класса?

    Ninazu
    @Ninazu
    Можно ловить все ошибки в одном месте

    <?php
    
    class Response {
    
    	public function sendResponse(array $data) {
    		echo json_encode($data);
    
    		return true;
    	}
    
    	public function sendError(string $message) {
    		echo json_encode(['error' => $message]);
    
    		return false;
    	}
    }
    
    class ErrorHandler {
    
    	private $response;
    
    	public function __construct(Response $response) {
    		$this->response = $response;
    	}
    
    	public function handlerError($error_code, $message, $file = null, $line = null) {
    		if ($error_code) {
    			throw new Exception($message, $error_code);
    		}
    
    		return true;
    	}
    
    	public function handlerShutdown() {
    		$error = error_get_last();
    
    		if ($error) {
    			$this->handlerException(new Error($error['message'], $error['type']));
    		}
    
    		exit(0);
    	}
    
    	public function handlerException(Throwable $exception) {
    		if (ob_get_length()) {
    			ob_end_clean();
    		}
    
    		if (!headers_sent()) {
    			return $this->response->sendError($exception->getMessage());
    		}
    
    		return true;
    	}
    }
    
    $response = new Response();
    $handler = new ErrorHandler($response);
    register_shutdown_function([$handler, 'handlerShutdown']);
    set_error_handler([$handler, 'handlerError']);
    set_exception_handler([$handler, 'handlerException']);
    
    #region Logic
    
    $cnt = 0;
    
    if ($cnt === 0) {
    	throw new Exception("Нулевое количество");
    }
    
    #endregion
    
    $response->sendResponse([
    	'message' => "Всё окей"
    ]);
    Ответ написан
    2 комментария
  • Зачем нужны абстрактные классы и интерфейсы в php?

    Ninazu
    @Ninazu
    1. Абстрактный класс нельзя создать, только создать обьект от наследуемого класса
    2. Абстрактный класс может содержать реализацию, в отличии от интерфейса
    3. Абстрактный класс может содержать абстрактные методы, которые необходимо будет реализовать в дочерних классах
    4. Можно имплементировать сразу несколько интерфейсов, а наследовать только от одного класса.
    5. Трейты очень хорошо комбинируются с интерфейсами

    Осознание зачем это нужно, прийдёт к вам в процессе использования)) Почитайте также про SOLID, и попробуйте реализовать эти принципы без абстракций и интерфейсов)

    P.S. Домашнее задание
    Есть три класса. Квадрат, Прямоугольник, Круг. И класс Ящик. Мы добавляем в ящик, произвольные наборы из фигур, и нужно посчитать площадь всех фигур в ящике.
    Ответ написан
  • Почему AJAX запрос обрывается на 5-ой минуте выполнения PHP скрипта, к которому обращаемся через AJAX на JavaScript?

    Ninazu
    @Ninazu
    Дело в серверной части. Время жизни скрипта видимо 5-ть минут. Это ненормально ждать ответа минутами. Если логика того требует то переделайте на WebSocket. Ну или на крайний случай LongPooling, хотя я бы всё же пересмотрел логику и двигался в сторону либо WebSocket, либо очередей и получение данных со следующими запросами
    Ответ написан
    Комментировать