Архив рубрики: PHP

Установка капчи reCAPTCHA v2 на сайт без отправки формы

Технически задача выглядит так:  на клиенте пользователь нажимает галочку «Я не робот» (описание от Google), по нажатии какойто кнопки — проверяем деймтвитель но ли капча пройдена.

Html (клиент):

<script type="text/javascript">
              var onloadCallback = function() {
                grecaptcha.render('capcha_element', {
                  'sitekey' : 'ключ сайта',
                   hl : "ru"
                });
              };
</script>
<div class="border border-light p-5" id="RegistrationDiv">
    <p class="h4 mb-4 text-center">Регистрация</p>        
    <input type="email" name="RegisterFormEmail" id="RegisterFormEmail" class="form-control mb-4" placeholder="E-mail">    
    <input type="password" name="RegisterFormPassword" id="RegisterFormPassword" class="form-control" placeholder="Пароль" aria-describedby="RegisterFormPasswordHelpBlock">
    <small id="RegisterFormPasswordHelpBlock" class="form-text text-muted mb-4">Минимальная длина 8 симоволов</small>

    <div id="capcha_element"></div>    

    <button id="RegistrationStartButton" onclick="RegistrationStart()" class="btn btn-success my-4 btn-block">Зарегистрироваться</button>
</div>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
<script>
function GetCapchaData(){
if (typeof grecaptcha.getResponse=="function") {
return grecaptcha.getResponse(); 
} else {
return ""; 
};
}
function RegistrationStart(){ 
$.post("registration.php", {
capcha: GetCapchaData()
})
.done(function( data ) {
});
}
</script>



PHP (сервер)

<?php
        $res=GetResponseCapcha($capcha);
        if (isset($res->success)):
           if ($res->success==true):
                  // капча пройдена, чтото делаем дальше
               else:
		 // это робот - пишем ошибку
           endif;
        endif;

function GetResponseCapcha($capcha){
    $ch = curl_init("https://www.google.com/recaptcha/api/siteverify");                
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $js["secret"]="секретный ключ сайта";
        $js["response"]=$capcha;
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $js);
        $res= json_decode(curl_exec($ch));    
   return $res;
}

SSL routines:ssl3_get_server_certificate:certificate verify failed

Эта ошибка может выходить на некоторых серверах при установце wss соединения WebSocket.

Решение:  отключаем проверку Peer

Amp\Loop::run(function () use (&$data) {
    $tlsc=new ClientTlsContext("");
    $tlw=$tlsc->withoutPeerVerification();
    $connectContext = (new ConnectContext)->withTlsContext($tlw);

    $connection = yield connect('wss://ezs.pupkin.ru:35502',$connectContext);                    
    yield $connection->close();                    
});

Многопоточность в PHP

Ну как известно штатно её нет (с). А иногда очень хочется. Предлагаемая пока альтернатива разработчками — функция Fork() которая по сути создает дочерний процесс, куда передает все открытые соединения, значения переменных и т.п. и продолжает в дочернем процессе с того момента с которого процесс в «родителе» начат.  Один нюанс — при завершении дочернего процесса — все соединения закрываются. Обходить этот нюанс можно посылая сигнал posix_kill(posix_getpid(), SIGHUP);  в дочернем процессе в случае нужды его завершить.

Таким образом «эталонная» реализация «многопоточности» в PHP будет выглядеть примерно так:

какойто код...
какойто код...
//предстоит длительная трудоемкая задача
$child_pid = pcntl_fork();
if ($child_pid==0){
	//длительная ресурсоемкая задача
	echo "--завершил дочерний процесс\n";
	posix_kill(posix_getpid(), SIGHUP);
} else {
	echo "--стартовал дочерний процесс\n";
};

 

WebSocket Ratchet сервер с одновременной прослушкой двух IP

Задача: поднять WebSocket сервер, одновременно слущающий и wss (для браузеров) и ws (для скриптов на PHP на том-же сервере).

Почему такой велосипед? Ну просто вот ну никак не удалось подобрать WebSocket клиент на PHP нормально работающий с WSS (SSL).

Решение:

$myClassMessage=new MessageService($UsersApi);

$loop = React\EventLoop\Factory::create();
$webSock = new React\Socket\Server('0.0.0.0:35500', $loop);
$webSock = new React\Socket\SecureServer($webSock, $loop, [
    'local_cert'        => 'епкуеп.crt', // path to your cert
    'local_pk'          => 'кепуке.key', // path to your server private key
    'allow_self_signed' => TRUE, // Allow self signed certs (should be false in production)
    'verify_peer' => FALSE
]);

$webServer = new Ratchet\Server\IoServer(
    new Ratchet\Http\HttpServer(
        new Ratchet\WebSocket\WsServer(
            $myClassMessage
        )
    ),
    $webSock,
    $loop        
);
$webSock2 = new React\Socket\Server('127.0.0.1:35501', $loop);

$webServer = new Ratchet\Server\IoServer(
    new Ratchet\Http\HttpServer(
        new Ratchet\WebSocket\WsServer(
            $myClassMessage
        )
    ),
    $webSock2,
    $loop        
);
$loop->run();