/** * Returns string of pseudo random characters * @param integer $len Length of desired string * @param string $chars String of allowed characters * @param callable $cb Callback * @param integer $pri Priority of EIO operation * @param boolean $hang If true, we shall use /dev/random instead of /dev/urandom and it may cause a delay * @return string */ public static function randomString($len = null, $chars = null, $cb = null, $pri = 0, $hang = false) { if ($len === null) { $len = 64; } if ($chars === null) { $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.'; } if ($cb === null) { Daemon::log('[CODE WARN] \\PHPDaemon\\Utils\\Crypt::randomString: non-callback way is not secure.' . ' Please rewrite your code with callback function in third argument' . PHP_EOL . Debug::backtrace()); $r = ''; $m = strlen($chars) - 1; for ($i = 0; $i < $len; ++$i) { $r .= $chars[mt_rand(0, $m)]; } return $r; } $charsLen = strlen($chars); $mask = static::getMinimalBitMask($charsLen - 1); $iterLimit = max($len, $len * 64); static::randomInts(2 * $len, function ($ints) use($cb, $chars, $charsLen, $len, $mask, &$iterLimit) { if ($ints === false) { call_user_func($cb, false); return; } $r = ''; for ($i = 0, $s = sizeof($ints); $i < $s; ++$i) { // This is wasteful, but RNGs are fast and doing otherwise adds complexity and bias $c = $ints[$i] & $mask; // Only use the random number if it is in range, otherwise try another (next iteration) if ($c < $charsLen) { $r .= static::stringIdx($chars, $c); } // Guarantee termination if (--$iterLimit <= 0) { return false; } } $d = $len - strlen($r); if ($d > 0) { static::randomString($d, $chars, function ($r2) use($r, $cb) { call_user_func($cb, $r . $r2); }); return; } call_user_func($cb, $r); }, $pri, $hang); }
/** * Error handler * @param integer $errno * @param string $errstr * @param string $errfile * @param integer $errline * @param array $errcontext */ public static function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) { Daemon::$noError = false; $l = error_reporting(); if ($l === 0) { if (!Daemon::$restrictErrorControl) { return; } } elseif (!($l & $errno)) { return; } static $errtypes = [E_ERROR => 'Fatal error', E_WARNING => 'Warning', E_PARSE => 'Parse error', E_NOTICE => 'Notice', E_PARSE => 'Parse error', E_USER_ERROR => 'Fatal error (userland)', E_USER_WARNING => 'Warning (userland)', E_USER_NOTICE => 'Notice (userland)', E_STRICT => 'Notice (userland)', E_RECOVERABLE_ERROR => 'Fatal error (recoverable)', E_DEPRECATED => 'Deprecated', E_USER_DEPRECATED => 'Deprecated (userland)']; $errtype = $errtypes[$errno]; Daemon::log($errtype . ': ' . $errstr . ' in ' . $errfile . ':' . $errline . "\n" . Debug::backtrace()); if (Daemon::$context instanceof \PHPDaemon\Request\Generic) { Daemon::$context->out('<strong>' . $errtype . '</strong>: ' . $errstr . ' in ' . basename($errfile) . ':' . $errline . '<br />'); } }
/** * @param string $prop * @return void */ public function __unset($prop) { Daemon::log('[CODE WARN] Unsetting property ' . json_encode($prop) . ' in object of class ' . get_class($this) . PHP_EOL . Debug::backtrace()); unset($this->{$prop}); }
/** * Stop the workers * @param $n - integer - number of workers to stop * @return boolean - success */ protected function stopWorkers($n = 1) { Daemon::log('--' . $n . '-- ' . Debug::backtrace() . '-----'); $n = (int) $n; $i = 0; foreach ($this->workers->threads as &$w) { if ($i >= $n) { break; } if ($w->shutdown) { continue; } if ($w->reloaded) { continue; } $w->stop(); ++$i; } $this->lastMpmActionTs = microtime(true); return true; }