/** * This is myMethod! * * @param string|array $s param1 * @param int $i param2 * @param Example|null $e param3 * @param bool $b param4 * @param array/null $a param5 * @return array|bool Returns FALSE if error occurred */ public function myMethod($s, $i, $e = null, $b = true, array $a = null) { if (!ReflectionTypeHint::isValid()) { return false; } //... }
/** * Исправляет клавиатурные опечатки в тексте. * * @param scalar|null $s Текст в кодировке UTF-8. * @param int $mode Константы self::SIMILAR_CHARS и/или self::KEYBOARD_LAYOUT, * (их можно комбинировать). Описание констант см. выше. * При использовании self::KEYBOARD_LAYOUT время работы увеличивается примерно в 10 раз. * @param array &$words Ассоц. массив со словами, которые были исправлены: * в ключах оригиналы, в значениях исправленные слова. * @return string|bool Returns FALSE if error occured */ public function parse($s, $mode = self::SIMILAR_CHARS, array &$words = null) { if (!ReflectionTypeHint::isValid()) { return false; } if (!is_string($s)) { return $s; } if ($mode < self::SIMILAR_CHARS || $mode > (self::SIMILAR_CHARS | self::KEYBOARD_LAYOUT | self::ADD_FIX)) { trigger_error('Unknown mode', E_USER_WARNING); return false; } $this->mode = $mode; #вырезаем и заменяем некоторые символы $additional_chars = array(""); #http://ru.wikipedia.org/wiki/Диакритические_знаки $s = UTF8::diactrical_remove($s, $additional_chars, $is_can_restored = true, $restore_table); $this->words = array(); $s = $this->_parse1($s); $s = $this->_parse2($s); $s = UTF8::diactrical_restore($s, $restore_table); $words = $this->words; return $s; }
/** * Главный метод * * @param scalar|null $s Текст в кодировке UTF-8. * @param array|null $words Ассоц. массив со словами, которые были исправлены: * в ключах оригиналы, в значениях исправленные слова. * @return string|bool returns FALSE if error occured */ public function parse($s, array &$words = null) { if (!ReflectionTypeHint::isValid()) { return false; } if (!is_string($s)) { return $s; } #пропускаем текст, в котором нет букв [ЕеЁё] if ($this->_is_skip($s)) { return $s; } #speed improve if (!(is_array($this->dic) || is_resource($this->db))) { if (function_exists('dba_open') && array_key_exists('cdb', dba_handlers(true))) { $this->db = dba_open($this->_filename('cdb'), 'r', 'cdb'); if ($this->db === false) { return $s; } } elseif ($this->is_work_for_cdb_only) { return $s; } else { include $this->_filename('php'); } } #вырезаем и заменяем некоторые символы $additional_chars = array(""); $s = UTF8::diactrical_remove($s, $additional_chars, $is_can_restored = true, $restore_table); $this->words = array(); #заменяем слова из текста, минимальная длина слова -- 3 буквы, меньше нельзя $s = preg_replace_callback('/ (' . $this->ru . ') #1 первая буква ((?:' . $this->ru_lc . '){2,}+) #2 остальные буквы (?! \\.(?>[\\x00-\\x20]+|\\xc2\\xa0)+ #\\xc2\\xa0 = (?> (?:' . $this->ru_lc . ') | (?:' . $this->ru_uc . '){2} #пример: долл. США | [\\x21-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7e] ) | \\.[\\x21-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7e] ) /sxSX', array(&$this, '_word'), $s); $s = UTF8::diactrical_restore($s, $restore_table); $words = $this->words; return $s; }
/** * Returns derivatives from the password to be able to log in (authorization), * regardless of keyboard layout (language input) and pressing [Caps Lock] or [Shift] buttins. * Character encoding — UTF-8. * * @param string $password Password * @param string $lang Language * @return array|bool A few password forms * Returns FALSE if error occurred */ public static function keyboard_forms($password, $lang = 'ru') { if (!ReflectionTypeHint::isValid()) { return false; } $passwords = array(self::_keyboard_layout_conv($password, $lang, 'en'), self::_keyboard_layout_conv($password, 'en', $lang)); for ($c = count($passwords), $i = 0; $i < $c; $i++) { $passwords[] = self::_keyboard_capslock_invert($passwords[$i]); } return $passwords; }
/** * * @param string $s строка для проверки * @param string $delta ширина найденного фрагмента в словах * (кол-во слов от матного слова слева и справа, максимально 10) * @param string $continue строка, которая будет вставлена в начале и в конце фрагмента * @param bool $is_html расценивать строку как HTML код? * в режиме $is_html === TRUE html код игнорируется, а html сущности заменяются в "чистый" UTF-8 * @param string|null $replace строка, на которую заменять матный фрагмент, например: '[ой]' ($replace д.б. в кодировке $charset) * опция работает в PHP >= 5.2.0 * @param string $charset кодировка символов (родная кодировка -- UTF-8, для других будет прозрачное перекодирование) * @return bool|string|int|null Если $replace === NULL, то возвращает FALSE, если мат не обнаружен, иначе фрагмент текста с матерным словом. * Если $replace !== NULL, то возвращает исходную строку, где фрагменты мата заменены на $replace. * В случае возникновения ошибки возвращает код ошибки > 0 (integer): * * PREG_INTERNAL_ERROR * * PREG_BACKTRACK_LIMIT_ERROR (see also pcre.backtrack_limit) * * PREG_RECURSION_LIMIT_ERROR (see also pcre.recursion_limit) * * PREG_BAD_UTF8_ERROR * * PREG_BAD_UTF8_OFFSET_ERROR (since PHP 5.3.0) * Или -1, если ReflectionTypeHint вернул ошибку */ public static function parse($s, $delta = 3, $continue = "…", $is_html = true, $replace = null, $charset = 'UTF-8') { if (!ReflectionTypeHint::isValid()) { return -1; } if ($s === null) { return null; } static $re_badwords = null; if ($re_badwords === null) { #предлоги русского языка: #[всуо]| #по|за|на|об|до|от|вы|вс|вз|из|ис| #под|про|при|над|низ|раз|рас|воз|вос| #пооб|повы|пона|поза|недо|пере|одно| #полуза|произ|пораз|много| $pretext = array('[уyоoаa]_? (?=[еёeхx])', '[вvbсc]_? (?=[хпбмгжxpmgj])', '[вvbсc]_?[ъь]_? (?=[еёe])', 'ё_? (?=[бb6])', '[вvb]_?[ыi]_?', '[зz3]_?[аa]_?', '[нnh]_?[аaеeиi]_?', '[вvb]_?[сc]_? (?=[хпбмгжxpmgj])', '[оo]_?[тtбb6]_? (?=[хпбмгжxpmgj])', '[оo]_?[тtбb6]_?[ъь]_? (?=[еёe])', '[иiвvb]_?[зz3]_? (?=[хпбмгжxpmgj])', '[иiвvb]_?[зz3]_?[ъь]_? (?=[еёe])', '[иi]_?[сc]_? (?=[хпбмгжxpmgj])', '[пpдdg]_?[оo]_? (?> [бb6]_? (?=[хпбмгжxpmgj]) | [бb6]_? [ъь]_? (?=[еёe]) | [зz3]_? [аa] _? )?', '[пp]_?[рr]_?[оoиi]_?', '[зz3]_?[лl]_?[оo]_?', '[нnh]_?[аa]_?[дdg]_? (?=[хпбмгжxpmgj])', '[нnh]_?[аa]_?[дdg]_?[ъь]_? (?=[еёe])', '[пp]_?[оoаa]_?[дdg]_? (?=[хпбмгжxpmgj])', '[пp]_?[оoаa]_?[дdg]_?[ъь]_? (?=[еёe])', '[рr]_?[аa]_?[зz3сc]_? (?=[хпбмгжxpmgj])', '[рr]_?[аa]_?[зz3сc]_?[ъь]_? (?=[еёe])', '[вvb]_?[оo]_?[зz3сc]_? (?=[хпбмгжxpmgj])', '[вvb]_?[оo]_?[зz3сc]_?[ъь]_? (?=[еёe])', '[нnh]_?[еe]_?[дdg]_?[оo]_?', '[пp]_?[еe]_?[рr]_?[еe]_?', '[oо]_?[дdg]_?[нnh]_?[оo]_?', '[кk]_?[oо]_?[нnh]_?[оo]_?', '[мm]_?[уy]_?[дdg]_?[oоaа]_?', '[oо]_?[сc]_?[тt]_?[оo]_?', '[дdg]_?[уy]_?[рpr]_?[оoаa]_?', '[хx]_?[уy]_?[дdg]_?[оoаa]_?', '[мm]_?[нnh]_?[оo]_?[гg]_?[оo]_?(?![еёe]\\s)', '[мm]_?[оo]_?[рpr]_?[дdg]_?[оoаa]_?', '[мm]_?[оo]_?[зz3]_?[гg]_?[оoаa]_?', '[дdg]_?[оo]_?[лl]_?[бb6]_?[оoаa]_?', '[оo]_?[сc]_?[тt]_?[рpr]_?[оo]_?'); $badwords = array('([х]_?[й])', '(?<=\\PL) %RE_PRETEXT%? [hхx]_?[уyu]_?[ийiеeёяюju] #хуй, хуя, хую, хуем, хуёвый, охуительный #исключения: (?<! _hue(?=_) #HUE -- цветовая палитра | _hue(?=so_) #hueso -- испанское слово | _хуе(?=дин) #Хуедин -- город в Румынии | _hyu(?=ndai_) #Hyundai -- марка корейского автомобиля | _хуе(?=ндай_) #Hyundai -- марка корейского автомобиля )', '(?<=\\PL) %RE_PRETEXT%? [hхx]_?[уyu]_?[ийi1]_?[лoо0] #хуйлo #исключения: (?<! _hue(?=_) #HUE -- цветовая палитра | _hue(?=so_) #hueso -- испанское слово | _хуе(?=дин) #Хуедин -- город в Румынии | _hyu(?=ndai_) #Hyundai -- марка корейского автомобиля )', '(?<=\\PL) %RE_PRETEXT%? [hхx]_?[уyu]_?[л]_?[oо0] #ху*лo #исключения: (?<! _hue(?=_) #HUE -- цветовая палитра | _hue(?=so_) #hueso -- испанское слово | _хило(?=_) #хило | _хуе(?=дин) #Хуедин -- город в Румынии | _hyu(?=ndai_) #Hyundai -- марка корейского автомобиля )', '(?<=\\PL) %RE_PRETEXT%? [hхx]_?[ийi1]_?[лl]_?[oоo0] #ху*лo #исключения: (?<! _hue(?=_) #HUE -- цветовая палитра | _hue(?=so_) #hueso -- испанское слово | _хуе(?=дин) #Хуедин -- город в Румынии | _хило(?=_) #хило | _hyu(?=ndai_) #Hyundai -- марка корейского автомобиля )', '(?<=\\PL) %RE_PRETEXT%? [hхx]_?[ийi1]_?[l]_?[oоo0] #ху*лo #исключения: (?<! _hue(?=_) #HUE -- цветовая палитра | _hue(?=so_) #hueso -- испанское слово | _хуе(?=дин) #Хуедин -- город в Румынии | _хило(?=_) #хило | _hyu(?=ndai_) #Hyundai -- марка корейского автомобиля )', '(?<=\\PL) %RE_PRETEXT%? [пp]_?[иieеё]_?[зz3]_?[дd](?=_?[:vowel:])', '(?<=\\PL) [cсs]_?[oaао]_?[cсs]_?[iи]\\b', '(?<=\\PL) [oо]_?[tт]_?[cсs]_?[oо]_?[cсs]_?[iи]', '(?<=\\PL) [cсs]_?[oо]_?[cсs]_?[аa]_?[тt]_?[ь]', '(?<=\\PL) %RE_PRETEXT%? [eеё]_? #исключения (?<!н[eе][её]_|т_е_) #неё, т.е. большие [бb6]_? (?= [уyиi]_ #ебу, еби | [ыиiоoaаеeёуy]_?[:consonant:] #ебут, ебать, ебись, ебёт, поеботина, выебываться, ёбарь #исключения (?<!_ebo[kt](?=_)|буд) #ebook, eboot, ее будут (?<!_ebo[kt](?=_)|бур) #ebook, eboot, ее будут (?<!_ebo[kt](?=_)|был) #ebook, eboot, е был (?<!_и[kt](?=_)|бай) #и бай | [лl](?:[оoаaыиiя]|ya) #ебло, ебла, ебливая, еблись, еблысь, ёбля | [нn]_?[уy] #ёбнул, ёбнутый | [кk]_?[аa] #взъёбка | [сc]_?[тt] #ебсти )', '(?<=\\PL) %RE_PRETEXT% (?<= \\pL\\pL|\\pL_\\pL_) [eеё]_?[бb6] #долбоёб, дураёб, изъёб, заёб, заебай, разъебай, мудоёбы ', '(?<=\\PL) я[еуи][бb][уy] (?=\\PL)', '(?<=\\PL) ёб (?=\\PL)', '\\b[ёeе]_?[бb]\\b', '\\b[ёeе]_?[бb]_?[tт]\\b', '[ё]_?[бb] ', '([т]_?[в]_?[о]_?[ю]_?[м]_?[а]_?[т]_?[ь])', '(?<=\\PL) ибу (?=\\PL)', '(?<=\\PL) %RE_PRETEXT%? [бb6]_?[лl]_?(?:я|ya)(?: _ #бля | _?[тдtd] #блять, бляди )', '(?<=\\PL) [пp]_?[иieе]_?[дdg]_?[eеaаoо]_?[rpр]', '(?<=\\PL) \\w*[пp]_?[иieе]_?[дdg]_?[eеaаoо]_?[rpр]\\b #исключения: (?<!импидор) #Импидор ', '(?<=\\PL) [дв]_?[еэ]_?[бb]_?[иi]_?[лl]\\b', '(?<=\\PL) [yу][р]_?[оo]_?[д]_?(?![л])', '(?<=\\PL) [мm]_?[уy]_?[дdg]_?[аa] #мудак, мудачок #исключения: (?<!_myda(?=s_)) #Chelonia mydas -- морская зеленая (суповая) черепаха ', '(?<=\\PL) [zж]_?h?_?[оo]_?[pп]_?[aаyуыiеeoо]', '(?<=\\PL) [мm]_?[аa]_?[нnh]_?[дdg]_?[aаyуыiеeoо]_ #манд[ауыео] #исключения: (?<! манда(?=[лн]|рин) | manda(?=[ln]|rin) ) ', '(?<=\\PL) [гg]_?[оo]_?[вvb]_?[нnh]_?[оoаaяеeyу]', '(?<=\\PL) f_?u_?[cс]_?k', '[^р]_?[scс]_?[yуu]_?[kк]_?[aаiи]', '[^р]_?[scс]_?[yуu]_?[4ч]_?[кk]', '\\bл_?[оo]_?[хx]\\b', '(?<=\\PL) [шщ]_?[лl]_?[ю]_?[хш]'); $trans = array('_' => '\\x20', '\\pL' => '[^\\x20\\d]', '\\PL' => '[\\x20\\d]', '[:vowel:]' => '[аеиоуыэюяёaeioyu]', '[:consonant:]' => '[^аеиоуыэюяёaeioyu\\x20\\d]'); $re_badwords = str_replace('%RE_PRETEXT%', '(?:' . implode('|', $pretext) . ')', '~' . implode('|', $badwords) . '~sxuSX'); $re_badwords = strtr($re_badwords, $trans); } $s = UTF8::convert_from($s, $charset); $replace = UTF8::convert_from($replace, $charset); $ss = $s; #saves original string if ($is_html) { #скрипты не вырезаем, т.к. м.б. обходной маневр на с кодом на javascript: #<script>document.write('сло'+'во')</script> #хотя давать пользователю возможность использовать код на javascript нехорошо $s = is_callable(array('HTML', 'strip_tags')) ? HTML::strip_tags($s, null, true, array('comment', 'style', 'map', 'frameset', 'object', 'applet')) : strip_tags($s); #заменяем html-сущности в "чистый" UTF-8 $s = UTF8::html_entity_decode($s, $is_htmlspecialchars = true); } if (strtoupper(substr($charset, 0, 3)) === 'UTF') { #remove combining diactrical marks $additional_chars = array(""); $s = UTF8::diactrical_remove($s, $additional_chars); } #ВотБ/\яПидорыОхуелиБлятьНахуйПохуйПи3децПолный if (version_compare(PHP_VERSION, '5.2.0', '>=')) { $s = preg_replace('~ [\\p{Lu}3] (?>\\p{Ll}+|/\\\\|[@36]+)++ #Вот (?= [\\p{Lu}3] (?:\\p{Ll} |/\\\\|[@36] ) ) #Бля ~sxuSX', '$0 ', $s); } $s = UTF8::lowercase($s); #получаем в массив только буквы и цифры #"с_л@о#во,с\xc2\xa7лово.Слово" -> "с л о во с лово слово слово слово слово" preg_match_all('~(?> \\xd0[\\xb0-\\xbf]|\\xd1[\\x80-\\x8f\\x91] #[а-я] | /\\\\ #л | @ #а | [a-z\\d]+ )+ ~sxSX', $s, $m); $s = ' ' . implode(' ', $m[0]) . ' '; $trans = array('/\\' => 'л', '@' => 'а'); $s = strtr($s, $trans); #цифровые подделки под буквы $trans = array('~ [3з]++ [3з\\x20]*+ ~sxuSX' => 'з', '~ [6б]++ [6б\\x20]*+ ~sxuSX' => 'б'); $s = preg_replace(array_keys($trans), array_values($trans), $s); #убираем все повторяющиеся символы, ловим обман типа "х-у-у-й" #"сллоооовоо слово х у у й" --> "слово слово х у й" $s = preg_replace('/( [\\xd0\\xd1][\\x80-\\xbf] \\x20? #optimized [а-я] | [a-z\\d] \\x20? ) \\1+ /sxSX', '$1', $s); //echo $s if ($replace === null || version_compare(PHP_VERSION, '5.2.0', '<')) { $result = preg_match($re_badwords, $s, $m, PREG_OFFSET_CAPTURE); if (function_exists('preg_last_error') && preg_last_error() !== PREG_NO_ERROR) { return preg_last_error(); } if ($result === false) { return 1; } #PREG_INTERNAL_ERROR = 1 if ($result && $replace === null) { list($word, $offset) = $m[0]; $s1 = substr($s, 0, $offset); $s2 = substr($s, $offset + strlen($word)); $delta = intval($delta); if ($delta === 0) { $fragment = '[' . trim($word) . ']'; } else { if ($delta < 1 || $delta > 10) { $delta = 3; } preg_match('/ (?> \\x20 (?>[\\xd0\\xd1][\\x80-\\xbf]|[a-z\\d]+)++ ){1,' . $delta . '}+ \\x20?+ $/sxSX', $s1, $m1); preg_match('/^ (?>[\\xd0\\xd1][\\x80-\\xbf]|[a-z\\d]+)*+ #ending \\x20?+ (?> (?>[\\xd0\\xd1][\\x80-\\xbf]|[a-z\\d]+)++ \\x20 ){0,' . $delta . '}+ /sxSX', $s2, $m2); $fragment = (ltrim(@$m1[0]) !== ltrim($s1) ? $continue : '') . trim((isset($m1[0]) ? $m1[0] : '') . '[' . trim($word) . ']' . (isset($m2[0]) ? $m2[0] : '')) . (rtrim(@$m2[0]) !== rtrim($s2) ? $continue : ''); } return UTF8::convert_to($fragment, $charset); } /* $wordsfinal=array( 'еб' ,'eb' ,'ёб' ,'ёb' ); $patternfinal = '/('.join($wordsfinal, '|').')/iu'; //print_r($s); //print_r($pattern_final); $resultNew = preg_match($patternfinal, $s,$m,PREG_OFFSET_CAPTURE); echo "ddd"; print_r($m); if ($resultNew === false) return 1; #PREG_INTERNAL_ERROR = 1 if ($resultNew) { return true; } //print_r($resultNew); //print_r($re_badwords); //print_r($m); */ /* $censor = new CensorWords; $censor->setDictionary("ru"); //$censor->generateCensorChecks(true); $resNew = $censor->censorString($s,true); print_r($resNew); if( count($resNew['matched'])>0 ) { return true; } */ //$pattern_final = '/('.join($words_final, '|').')/i'; //$resultNew = preg_match($pattern_final, $s); //print_r($resultNew); //print_r($pattern_final); //if ($result === false) return 1; #PREG_INTERNAL_ERROR = 1 //if ($result && $replace === null) //{ // return UTF8::convert_to($fragment, $charset); //} return false; } $result = preg_match_all($re_badwords, $s, $m); if (function_exists('preg_last_error') && preg_last_error() !== PREG_NO_ERROR) { return preg_last_error(); } if ($result === false) { return 1; } #PREG_INTERNAL_ERROR = 1 if ($result > 0) { #d($s, $m[0]); $s = $ss; #замена матного фрагмента на $replace foreach ($m[0] as $w) { $re_w = '~' . preg_replace_callback('~(?:/\\\\|[^\\x20])~suSX', array('self', '_make_regexp_callback'), $w) . '~sxuiSX'; $ss = preg_replace($re_w, $replace, $ss); #d($re_w); } while ($ss !== $s) { $ss = self::parse($s = $ss, $delta, $continue, $is_html, $replace, 'UTF-8'); } } return UTF8::convert_to($ss, $charset); }
/** * * @param string|null $s * @param string|array $from * @param string|null $to * @return string|bool|null Returns FALSE if error occurred */ public static function strtr($s, $from, $to = null) { if (!ReflectionTypeHint::isValid()) { return false; } if (is_null($s)) { return $s; } if (is_array($from)) { return strtr($s, $from); } #speed improve $keys = self::str_split($from); $values = self::str_split($to); if ($keys === false || $values === false) { return false; } $table = array_combine($keys, $values); if (!is_array($table)) { return false; } return strtr($s, $table); }
/** * Converts malformed JSON to well-formed JSON * Hint: normalizes a "dirty" JSON string, coming from JavaScript * * @param string|null $s The json string being normalized * @return string|bool|null Returns FALSE if error occurred */ public static function normalize($s) { if (!ReflectionTypeHint::isValid()) { return false; } if (is_null($s)) { return $s; } $s = preg_replace_callback('~(?> #comments (\\/\\* .*? \\*\\/) #1 multi line comment | (\\/\\/ [^\\r\\n]*+) #2 single line comment #spaces | (\\s++) #3 #strings | " ((?>[^"\\\\]+ |\\\\.)*) " #4 | \' ((?>[^\'\\\\]+|\\\\.)*) \' #5 #trailing commas | (,) #6 (?> \\/\\* .*? \\*\\/ #multi line comment | \\/\\/ [^\\r\\n]*+ #single line comment | \\s++ )*+ (?=[\\]}]) #keys | ([a-zA-Z\\d_]++) #7 (?> \\/\\* .*? \\*\\/ #multi line comment | \\/\\/ [^\\r\\n]*+ #single line comment | \\s++ )*+ (?=:) ) ~sxuSX', array('self', '_normalize'), $s); if (!is_string($s)) { return false; } return $s; }
/** * Многопоточная проверка существования ссылок через cURL. * Для HTTP используется HEAD запрос. * * @param string|array $url строка или индексированный массив с ссылками, рекомендуется проверять по 50 ссылок * @param int|digit $timeout время ожидания ответа сервера * есть очень тормозные и загруженные сайты, меньше 30 сек. ставить не рекомендуется * @return array|bool ассоц. массив, где ключи это URL'ы, а значения это коды ответа сервера * если код ответа 0, то соединение установить не удалось * returns FALSE if error occured */ public static function exists($url, $timeout = 30) { if (!ReflectionTypeHint::isValid()) { return false; } $urls = (array) $url; #создаем обработчик для параллельной работы с URL'ами $mh = curl_multi_init(); if ($mh === false) { return false; } #создаём обработчики для каждого отдельного URL и добавляем их в $mh $handles = array(); foreach ($urls as $i => $url) { $options = array(CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => false, CURLOPT_AUTOREFERER => true, CURLOPT_MAXREDIRS => 5, CURLOPT_TIMEOUT => $timeout, CURLOPT_CONNECTTIMEOUT => 0, CURLOPT_HEADER => true, CURLOPT_NOBODY => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1); $handles[$i] = curl_init(); if ($handles[$i] === false) { return false; } if (!curl_setopt_array($handles[$i], $options)) { return false; } if (curl_multi_add_handle($mh, $handles[$i]) !== 0) { return false; } } #запускаем обработку $running = null; do { curl_multi_exec($mh, $running); #кол-во итераций цикла может быть большим, поэтому снижаем нагрузку на процессор, #давая возможность другим процессам поскорее завершить работу usleep(1000000 * 0.01); } while ($running > 0); $return = array(); foreach ($urls as $i => $url) { $info = curl_getinfo($handles[$i]); $return[$url] = $info['http_code']; } #закрываем обработчики foreach ($urls as $i => $url) { curl_multi_remove_handle($mh, $handles[$i]); } curl_multi_close($mh); return $return; }
/** * Заменяет домашнюю директорию на абсолютный путь. * * Пример вхождений, которые будут обработаны: * #замена внутри HTML * <a href="~/path/to/file.ext"> * <a href='~/path/to/file.ext'> * <a href="~:admin/path/to/file.ext"> * * #замена внутри CSS * url(~/path/to/file.ext) * * #замена внутри JS * <script type="text/javascript"> * <!--//<![CDATA[ * var hosts = { * 'admin' : '~:admin', * 'static' : '~:static', * 'media' : '~:media' * }; * //]]>--> * </script> * * Для сравнения неуклюжий синтаксис Smarty: * <a href="{'/path/to/file.ext'|project}"> * <a href="{'/path/to/file.ext'|project:'admin'}"> * * {literal} * <script type="text/javascript"> * <!--//<![CDATA[ * var hosts = { * 'admin' : '{/literal}{''|project:'admin'}{literal}', * 'static' : '{/literal}{''|project:'static'}{literal}', * 'media' : '{/literal}{''|project:'media'}{literal}' * }; * //]]>--> * </script> * {/literal} * * @param string $s * @param int|null $replace_count Кол-во произведённых замен * @return string|bool Returns FALSE if error occured */ public static function replace_home_path($s, &$replace_count = 0) { if (!ReflectionTypeHint::isValid()) { return false; } return preg_replace_callback(' ~ (?<= (["\']) #1 | \\( ) #путь должен начинаться с либо с корня (только абсолютные пути), либо с ключа поддомена \\~ \\~?+ (?> / | :([a-zA-Z]+[a-zA-Z\\d]*) #2 subdomain ) #([^"\'\\)\\x00-\\x20\\x7f-\\xff]*+) #3 #(?=(?(1) \\1 | \\) )) ((?(1) [^"\'\\x00-\\x20\\x7f-\\xff]*+ (?= \\1 ) | [^"\'\\)\\x00-\\x20\\x7f-\\xff]*+ (?= \\) ) )) #3 ~sxSX', array('self', '_replace_home_path'), $s, -1, $replace_count); }
/** * Treats the incoming string as template with the PHP code inserts, executes code and returns the result. * If necessary, checks the syntax of PHP code to the limitations, see self:: PHP_EXPRESSION_RE * * @param string|null $s Template content * @param array|null $vars Template variables * @param int $mode Mode, see self::EXECUTE_MODE_* * @param string $allow_funcs_re Regexp for possible helpers * @param bool $_is_check_syntax Used by self::valid() * @return string|bool Returns FALSE if error occurred */ public static function execute($s, array $vars = null, $mode = self::EXECUTE_MODE_PRESERVE, $allow_funcs_re = '(?:htmlspecialchars|rawurlencode)', $_is_check_syntax = false) { if (!ReflectionTypeHint::isValid()) { return false; } if (!is_string($s) || strpos($s, '<?') === false && strpos($s, '<%') === false) { return $s; } if ($mode === self::EXECUTE_MODE_NO_CHECK) { $s2 = preg_replace('~<%(.*?)%>~sSX', '<?$1?>', $s); } else { #check PHP code for valid syntax with limitations $class = __CLASS__; $s2 = preg_replace_callback('~<([\\?%]) .*? \\1>~sxSX', function (array $m) use($mode, $allow_funcs_re, $class) { $s = substr($m[0], 2, -2); if (preg_match('~^= (?<main> [\\x00-\\x20]*+ (?: ' . $class::PHP_EXPRESSION_RE . ' | ' . $allow_funcs_re . ' \\( (?&main) (?:, (?&main) )*+ \\) )++ [\\x00-\\x20]*+ ) $~sxSX', $s)) { return '<?' . $s . '?>'; } #if the code does not match the syntax with limitations if ($mode === $class::EXECUTE_MODE_REMOVE) { return ''; } if ($mode === $class::EXECUTE_MODE_PRESERVE) { return '< ?' . $s . '? >'; } if ($mode === $class::EXECUTE_MODE_HTML_QUOTE) { return htmlspecialchars('<?' . $s . '?>'); } trigger_error('Unknown mode', E_USER_ERROR); }, $s); } if ($_is_check_syntax) { if ($s2 !== $s) { return false; } return @self::_sandbox('<? return TRUE ?>' . $s2, null, false); } $s = self::_sandbox($s2, $vars, false); if (is_string($s) && $mode === self::EXECUTE_MODE_PRESERVE) { $s = preg_replace('~<\\x20\\? (.*?) \\?\\x20>~sxSX', '<?$1?>', $s); } return $s; }