Активация на акаунт

teroristd

Registered
Здравейте, имам регистрационна форма която след като бъде попълнена изпраща на имейла на потребителя активационен код, а потребителя го редиректва към активационната форма. Само че преди потребителя да бъде редиректнат се изпълнаява функцията mail() която много бави цялата работа. Има едно циклене 2-3 секунди което, не ми харесва. Кажете някакви идеи как може да се направи подобно нещо по бързо или друг наяин за активация.
 
teroristd каза:
Здравейте, имам регистрационна форма която след като бъде попълнена изпраща на имейла на потребителя активационен код, а потребителя го редиректва към активационната форма. Само че преди потребителя да бъде редиректнат се изпълнаява функцията mail() която много бави цялата работа. Има едно циклене 2-3 секунди което, не ми харесва. Кажете някакви идеи как може да се направи подобно нещо по бързо или друг наяин за активация.
Ако използваш header location го замени с мета рефреш. Дай малко код за да го ускорим ако можем. Реално проблема си идва от самото пренасочване. То бави доста. Тази функция също ще ти свърши работа за самият редирект.
PHP:
function redirect($url) {
    if(!headers_sent()) {
        //If headers not sent yet... then do php redirect
        header('Location: '.$url);
        exit;
    } else {
        //If headers are sent... do javascript redirect... if javascript disabled, do html redirect.
        echo '<script type="text/javascript">';
        echo 'window.location.href="'.$url.'";';
        echo '</script>';
        echo '<noscript>';
        echo '<meta http-equiv="refresh" content="0;url='.$url.'" />';
        echo '</noscript>';
        exit;
    }
}

// How to use
$url = "www.google.com";
redirect($url);

Дай да видим и мейла ако можем да го ускорим нещо. Все пак и е ресурс който бави малко или много.
 
Не самото пренасочване бави а изпращането на мейла. Тествал съм преди това само с пренасочване и става мигновенно. Иначе имам някакви проверки

Код:
if(empty($alabala)){
greshka
}
elseif($neshto_drugo){
greshka
}
else{
//ако всичко е точно
mail($to, $subject, $message, $headers);
header("Location:" . $view->link . "/activation/");
}
 
teroristd каза:
Не самото пренасочване бави а изпращането на мейла. Тествал съм преди това само с пренасочване и става мигновенно. Иначе имам някакви проверки

Код:
if(empty($alabala)){
greshka
}
elseif($neshto_drugo){
greshka
}
else{
//ако всичко е точно
mail($to, $subject, $message, $headers);
header("Location:" . $view->link . "/activation/");
}
Виж значи проблема ти идва изцуло от SMTP сървъра. Той отговаря за връзката и изпращането на съобщението и реолно той ти бави. Тук е коментирано точно това: http://stackoverflow.com/questions/5642143/methods-to-speed-up-php-mail
Бави ти конекцията към сървъра след което връщането и обработването на грешки ако има такива ако ли не хедърите, че всичко е наред след което изпращането на самото съобщение и това е. Ти не си на някакъв платен хостинг примерно да си подържа собствен SMTP. На локалния ще ти забави малко да.
 
След много часове ровене из нета мисля че, открих решение.

Код:
                $ch = curl_init();

                curl_setopt($ch, CURLOPT_URL,        'http://localhost/Site/public/Mail.php');
                curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
                curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1);

                curl_exec($ch);
                curl_close($ch);

Не съм запознат с curl и сега е хардкоднато но общо взето идеята е че, стартира някакъв скрипт и после връща контрола на текущата страница, без да чака завършването на задачата. Трябва да измисля как да го напиша по елегантно, с клас мейл и какво да правя в случай на грешка. До колкото разбрах няма калбек фунции.
 
teroristd каза:
След много часове ровене из нета мисля че, открих решение.

Код:
                $ch = curl_init();

                curl_setopt($ch, CURLOPT_URL,        'http://localhost/Site/public/Mail.php');
                curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
                curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1);

                curl_exec($ch);
                curl_close($ch);

Не съм запознат с curl и сега е хардкоднато но общо взето идеята е че, стартира някакъв скрипт и после връща контрола на текущата страница, без да чака завършването на задачата. Трябва да измисля как да го напиша по елегантно, с клас мейл и какво да правя в случай на грешка. До колкото разбрах няма калбек фунции.

Има как да няма!
http://bg2.php.net/manual/en/function.curl-errno.php
http://bg2.php.net/manual/en/function.curl-error.php
Тук може да ги намериш:
http://bg2.php.net/manual/en/book.curl.php

За класът просто си го поставяш в един метод и ако връщаш някакъв резултат от него ретърнваш curl_exec($ch);
 
dakata__92 каза:
За класът просто си го поставяш в един метод и ако връщаш някакъв резултат от него ретърнваш curl_exec($ch);

А как да го затворя после curl_close($ch);
 
teroristd каза:
dakata__92 каза:
За класът просто си го поставяш в един метод и ако връщаш някакъв резултат от него ретърнваш curl_exec($ch);

А как да го затворя после curl_close($ch);
В тази последователност. Не е нещо различно! :)
PHP:
<?php
// Create a curl handle to a non-existing location
$ch = curl_init('http://404.php.net/');

// Execute
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);

// Check if any error occurred
if(curl_errno($ch))
{
    echo 'Curl error: ' . curl_error($ch);
}

// Close handle
curl_close($ch);
?>
 
На този ред се подава стринг с път до скрипта.
Код:
curl_setopt($ch, CURLOPT_URL, 'http://localhost/Site/public/Mail.php');
Обаче се оказа че, когато го направя с класове(модел, контролер), трябва да подам функция. Самата функция се изпълнява(мейла е изпратен) но, изчезва търсеният ефект, демек трябва да се чака да се изпълни процеса преди връщането на контрола.

По принцип разните фреимуорци или сайтове използват някакви големи системи които не са писани на php(gearman например има и други някои платени), защото той бил single threaded език и не позволявал изпълнението на така наречените background процеси, които се използват за изпълнението на задачи които отнемат много време. Един вид юзъра стартира някакъв процес който отнема примерно 20мин. но вместо да седи и да чака да се изпълни той си жужи или дори може да илезне от сайта, но процеса си върви. Това може да се направи разбира се и с кронджоб, но хостинга трябва да го поддържа. Отделно програмно да го контролираш хич няма да е лесно. Абе с две думи пълна боза :D .
 
Нормално е да чакаш - нямаш асинхронна връзка. Но пък ако всичко е наред, изпращането на едно писмо, заедно с кода за потвърждение отнема не повече от 50 милисекунди при локални (за мрежата) мейл сървър (не ползвайте mail() функцията на PHP) и DNS сървър.
 
За един имейл ок няма проблеми чакаш. Ами ако сайта ти е по-голям и се регистрират да кажем 100 потребители едновреммено, тогава какво правиш? Забавянето ще е голямо. И не винаги отнема 50 милисекунди. Зависи от много неща. От два дена чета по въпроса и мого хора се полакват от доста голямо забавяне някои, дори повече от 20 секунди и то не на локалхост, а на платен хостинг. В моя случай става дума за един имейл, но може и да е друга задача или масов имейл.
 
teroristd каза:
За един имейл ок няма проблеми чакаш. Ами ако сайта ти е по-голям и се регистрират да кажем 100 потребители едновреммено, тогава какво правиш? Забавянето ще е голямо. И не винаги отнема 50 милисекунди. Зависи от много неща. От два дена чета по въпроса и мого хора се полакват от доста голямо забавяне някои, дори повече от 20 секунди и то не на локалхост, а на платен хостинг. В моя случай става дума за един имейл, но може и да е друга задача или масов имейл.
Въпроса е какво точно има и в Mail.php . По принцип е хубаво да използваш една инициализация в която да правиш сметките. Тоест ти викаш meil.php но това отново си бави. Все пак трябва да направиш конекция със сървърите за да можеш да изпратиш дадено съобщение. Ти реално погледнато не правиш някаква атака примерно към абев само за да конектнеш веднъж кода към домейна им тоест по-обикновенно казано да инициализираш веднъж към Abv.bg
curl_setopt($ch, CURLOPT_URL, 'http://abv.bg');
и да изпращаш като ненормален. Ти трябва към всяка една поща на потребителя да да изпратиш хедъри да получиш отговор от сърварите дали всичко е добре или има грешки след което да преминеш на следващата поща. Ако си дадеш целия код може и да се понамали малко времето но отново си е доста.
 
За щастие Дака открих решението :) , и то не само за пощата ами става за всякакви работи които, трябва да ги чакаш. И не е само това ами можеш дори да излезнеш от сайта или да пуснеш повече от една задача и всичко си работи. Най хубавото е че цялата работа не е с някакви външни системи, не е с кронджоб а си е с php и е суперелементарно за имплементация :D .
 
teroristd каза:
За щастие Дака открих решението :) , и то не само за пощата ами става за всякакви работи които, трябва да ги чакаш. И не е само това ами можеш дори да излезнеш от сайта или да пуснеш повече от една задача и всичко си работи. Най хубавото е че цялата работа не е с някакви външни системи, не е с кронджоб а си е с php и е суперелементарно за имплементация :D .
Ако не е с крон джоб то тогава предполагам, че е нещо подобно. Другият варянт е да го пуснеш на фрагменти на юзърите да обработват самите те тази информация :D
 
Не и така не е. Всичко си се обработва на сървъра. Виж какви тестове направих и всичко работи перфектно. Значи правя го мейла да се прати след пет минути. Излизам от сайта, влизам пак и пускам още един имеил, презтова време си жужа из сайта или излизам влизам, изобщо правя си каквото си искам и няма абсолютно никакво бавене или каквото и да е. Ако си юзър изобщо няма да разбереш че нещо цъка някъде, а то може да е бомба дори :D. След пет минути си получавам имейла, после и втория и т.н.
 
А е толкова елементарно, че чак не ми се вярва. Можеш да си правиш всякакви работи, примерно след 10 мин да изтриеш ред от базата данни или да създадеш нов, и не трябва да седиш в сайта да го чакаш :) .
 
teroristd каза:
Не и така не е. Всичко си се обработва на сървъра. Виж какви тестове направих и всичко работи перфектно. Значи правя го мейла да се прати след пет минути. Излизам от сайта, влизам пак и пускам още един имеил, презтова време си жужа из сайта или излизам влизам, изобщо правя си каквото си искам и няма абсолютно никакво бавене или каквото и да е. Ако си юзър изобщо няма да разбереш че нещо цъка някъде, а то може да е бомба дори :D. След пет минути си получавам имейла, после и втория и т.н.
Също като крона дърпаш от процесорното време! Както и да е дай лек пример за да видя дали се имплементира и при мен така лесно! :D
 
teroristd каза:
За един имейл ок няма проблеми чакаш. Ами ако сайта ти е по-голям и се регистрират да кажем 100 потребители едновреммено, тогава какво правиш? Забавянето ще е голямо. И не винаги отнема 50 милисекунди. Зависи от много неща. От два дена чета по въпроса и мого хора се полакват от доста голямо забавяне някои, дори повече от 20 секунди и то не на локалхост, а на платен хостинг. В моя случай става дума за един имейл, но може и да е друга задача или масов имейл.

Ако гледаме реалистично, тази ситуация е някъде дълбоко във фантастиката, освен ако не правиш сайта за регистрация в детските градини на София. Но дори в този случай ти ще имаш 100 ПАРАЛЕЛНИ нишки, инициализирани от УЕБ сървъра, а не през самия скрипт. С други думи, ако имаш техническите ресурси - положенето с времената няма да се влоши, поне не вдимо.

Колкото до забавяията - прави се анализ на проблема и се отстранява. Пак казвам - на първо време се ползва някакъв маилер клас като например http://swiftmailer.org/. В 80% от случите на забавяне проблема е свързан с резолването на домейните, което отсвоя страна може да е проблем при конфигурацията на използвания мейл сървър за изпращане на писмата или в самия ДНС сървър, който обслужва мейл сървъра. Друга причина за забавяния може да бъде задръстена по някаквапричина опашка на изходящите писма - например кофти функционираща антивирусна защита.
 
lamerko каза:
Ако гледаме реалистично, тази ситуация е някъде дълбоко във фантастиката, освен ако не правиш сайта за регистрация в детските градини на София. Но дори в този случай ти ще имаш 100 ПАРАЛЕЛНИ нишки, инициализирани от УЕБ сървъра, а не през самия скрипт. С други думи, ако имаш техническите ресурси - положенето с времената няма да се влоши, поне не вдимо.

Колкото до забавяията - прави се анализ на проблема и се отстранява. Пак казвам - на първо време се ползва някакъв маилер клас като например http://swiftmailer.org/. В 80% от случите на забавяне проблема е свързан с резолването на домейните, което отсвоя страна може да е проблем при конфигурацията на използвания мейл сървър за изпращане на писмата или в самия ДНС сървър, който обслужва мейл сървъра. Друга причина за забавяния може да бъде задръстена по някаквапричина опашка на изходящите писма - например кофти функционираща антивирусна защита.

Няма да споря, може и да е така. Факт е че при мене на локалхоста бави. Не знам дали теорията ти за сто паралелни нишки е вярна. Аз не мога да я тествам а и ти не можеш. Както казваш може да има причина която да не зависи от твоя сайт, но дори така да е ще изгубиш доста потребители докато анализираш и оправиш проблема. А може да ти потрябва да правиш и други тежки неща за които трябва да се чака. Проблема е комплексен. Затова Зенд, Ларавел и изобщо всички имат специални системи които, работят отзад така да се каже.
 
dakata__92 каза:
Също като крона дърпаш от процесорното време! Както и да е дай лек пример за да видя дали се имплементира и при мен така лесно! :D

Ето как става. Правя си проверките в няколко ифа и ако всичко е ок в елса пращам мейла и редиректвам на друга страница.


Код:
else {
                //По този начин юзъра не може да спре процеса
                ignore_user_abort(true);

                //Тука сетваме времето за изпълнение на скрипта на нула защото по дефаулт е 30 сек и мята грешка
                set_time_limit(0);

                //Редиректвам
                header("Location:" . $view->link . "/activation/");

                //Това са някакви буфери не ги разбирам :D 
                flush();
                ob_flush();

                //И затваряме сесията иначе не работи
                session_write_close();

                //Пращам си мейла
                $mail = new Mail();
                $mail->start();
            }

Код:
       //В самия мейл слагам забавяне 5 мин за теста но може и с някакви времена и дати да се направи и изобщо да не е мейл а каквото си решим
       sleep(300);

       $to = $dataEmail;
        $accCode = bin2hex(openssl_random_pseudo_bytes(16));
        $subject = 'Activation code';
        $message = 'алабала Activation code ';
        $headers = 'From: TestEmail@.com' . "\r\n" .
                'Content-Type: text/html; charset=UTF-8' . "\r\n" .
                'X-Mailer: PHP/' . phpversion();
        mail($to, $subject, $message, $headers);
 

Back
Горе