Commit 54810809 authored by wanjilong's avatar wanjilong

add: 项目初始化

parent 04b2ff49
<?php
use Yaf\Bootstrap_Abstract;
use Yaf\Dispatcher;
use App\Plugins\Hook;
use Yaf\Registry;
class Bootstrap extends Bootstrap_Abstract {
/**
* 项目基本初始化操作.
*
* @param Dispatcher $dispatcher
*/
public function _initProject(Dispatcher $dispatcher)
{
date_default_timezone_set('PRC');
//是否返回Response对象, 如果启用, 则Response对象在分发完成以后不会自动输出给请求端, 而是交给程序员自己控制输出.
$dispatcher->returnResponse(true);
$dispatcher->disableView();
}
/**
* autoload.
*
* @param Dispatcher $dispatcher
*/
public function _initLoader(Dispatcher $dispatcher)
{
$loader = Yaf\Loader::getInstance();
$loader->import(ROOT_PATH.'/vendor/autoload.php');
$loader->import(APP_PATH.'/library/helper.php');
}
public function _initConfig() {
//把配置保存起来
$arrConfig = Yaf\Application::app()->getConfig();
Registry::set('config', $arrConfig);
}
public function _initPlugin(Dispatcher $dispatcher) {
//注册一个插件
$objSamplePlugin = new Hook();
$dispatcher->registerPlugin($objSamplePlugin);
}
public function _initRoute(Dispatcher $dispatcher) {
//在这里注册自己的路由协议,默认使用简单路由
}
}
\ No newline at end of file
<?php
class Bootstrap extends Yaf\Bootstrap_Abstract{
/**
* 初始化配置文件
* 全局配置文件 ,环境配置文件 错误码配置文件等
*/
public function _initConfig() {
$globalConfig = Yaf\Application::app()->getConfig();
Yaf\Registry::set('cliConfig', $globalConfig);
}
/**
* 禁用视图
*/
public function _initView(\Yaf\Dispatcher $dispatcher) {
$dispatcher->disableView();
}
}
<?php
use Yaf\Controller_Abstract;
/**
* 每个项目按需定义异常处理,记录日志等,确定的异常请在自定义异常处理,详细在exception目录中查看
*/
class ErrorController extends Controller_Abstract
{
use \Helpers\ApiResponse;
public function errorAction($exception)
{
if (\Yaf\Application::app()->environ() == 'dev') {
// var_dump($exception);
}
if ($exception->getPrevious() !== NULL) {
$exception = $exception->getPrevious();
}
switch ($exception->getCode()) {
// 404
case YAF\ERR\NOTFOUND\MODULE:
case YAF\ERR\NOTFOUND\CONTROLLER:
case YAF\ERR\NOTFOUND\ACTION:
case YAF\ERR\NOTFOUND\VIEW:
// todo 各项目自定义
// log
// LogUtil::ERROR('error code'.$exc->getCode(), '', $exc);
$this->failed(10, 'failed', 'reason');
return false;
break;
default:
// todo 各项目自定义
// log
$reason = '服务器忙, 请稍后再试[' . $exception->getCode() . ']';
$this->failed($exception->getCode(), 'failed', $reason);
return false;
}
}
}
<?php
use Yaf\Controller_Abstract;
/**
* 不要删除默认的控制器,deploy等服务会调用此/indix/index接口,判断项目是否可用
*/
class IndexController extends Controller_Abstract
{
use \Helpers\ApiResponse;
public function IndexAction() {
$this->success();
}
}
<?php
namespace App\Exception;
use Helpers\ApiResponse;
use Yaf\Registry;
/**
* Class BaseException
* 自定义异常类的基类
*/
class BaseException extends \Exception
{
use ApiResponse;
public $msg;
public $code;
/**
* 构造函数,接收一个关联数组
* @param array $params 关联数组只应包含code、msg和errorCode,且不应该是空值
*/
public function __construct($params = [])
{
if (!is_array($params)) {
return;
}
$this->code = $params['code'] ?? Registry::get('config')->exception->user->code;
$this->msg = $params['msg'] ?? Registry::get('config')->exception->user->msg;
if (isset($params['cus']) && $this->cus && isset($this->cus[intval($params['cus'])]) && $this->base_code) {
$cus_code = intval($params['cus']);
$base_code = intval($this->base_code);
$this->code = $base_code + $cus_code;
$this->msg = $this->cus[$cus_code];
}
}
public function __get($name): bool
{
return false;
}
}
<?php
namespace App\Exception;
/*
* 重写Handle的render方法,实现自定义异常消息
*/
use Helpers\ApiResponse;
use Yaf\Registry;
class ErrorHandler
{
use ApiResponse;
private $http_code;
private $msg;
private $code;
public function render($errno, $errstr, $errfile, $errline)
{
$msg = ' file_name : '.$errfile . '<br> line_num : '.$errline . '<br> message : ' . $errstr;
if(_IS_DEBUG){
echo $msg;
exit;
}
$this->msg = appConfig('exception.sys.msg');
$this->code = appConfig('exception.sys.code');
$this->recordErrorLog($msg);
$this->failed($this->code, $this->msg);
}
/*
* 将异常写入日志
*/
private function recordErrorLog($msg)
{
// LogUtil::error('Error handler', $msg);
}
}
\ No newline at end of file
<?php
namespace App\Exception;
class ExceptionErrorCatch
{
public static function register()
{
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
set_exception_handler([__CLASS__, 'appException']);
set_error_handler([__CLASS__, 'appError'], E_ALL & ~E_DEPRECATED);
}
public static function appException(\Throwable $e)
{
$handler = new ExceptionHandler();
$handler->render($e);
exit;
}
public static function appError($errno, $errstr, $errfile, $errline)
{
$handler = new ErrorHandler();
$handler->render($errno, $errstr, $errfile, $errline);
exit;
}
}
\ No newline at end of file
<?php
namespace App\Exception;
/*
* 重写Handle的render方法,实现自定义异常消息
*/
use Helpers\ApiResponse;
use Yaf\Registry;
class ExceptionHandler
{
use ApiResponse;
private $msg;
private $code;
public function render(\Throwable $e)
{
if ($e instanceof BaseException)
{
// 自定义异常
$this->code = $e->code;
$this->msg = $e->msg;
}
else{
// 服务器未处理异常
if(_IS_DEBUG){
$message = $e->getMessage();
$file_name = $e->getFile();
$line_num = $e->getLine();
echo ' file_name : '.$file_name . '<br> line_num : '.$line_num . '<br> message : ' . $message;
exit;
}
$this->msg = appConfig('exception.sys.msg');
$this->code = appConfig('exception.sys.code');
$this->recordErrorLog($e);
}
$this->failed($this->code, $this->msg);
}
/*
* 将异常写入日志
*/
private function recordErrorLog($e)
{
if($e instanceof \ErrorException || $e instanceof \Exception){
$message = $e->getMessage();
$file_name = $e->getFile();
$line_num = $e->getLine();
$msg = ' file_name : '.$file_name . ' line_num : '.$line_num . ' message : ' . $message;
// LogUtil::error('exception handler', $msg);
}
if(is_string($e) || is_int($e)){
// LogUtil::error('exception handler', $e);
}
}
}
\ No newline at end of file
<?php
namespace App\Exception\custom;
/**
* 异常code规则:前3位是大类,后三位是细分
* 比如 参数异常、验签异常、用户异常 三大类,分别是 101000、102000、103000
* 用户异常又细分,比如未登录103001、密码错误103002
*/
class Code
{
const PAY = 101000;
const REFUND = 102000;
}
\ No newline at end of file
<?php
namespace App\Exception\custom;
use App\Exception\BaseException;
class PayException extends BaseException
{
protected $base_code = Code::PAY;
protected $cus = [
0 => '用户已通过个人认证,无需重复认证',
1 => '企业已通过认证,无需重复认证'
];
}
<?php
namespace Enum;
class Second
{
const SECOND = 1; // 1秒
const ONE_MINUTE = 60; // 1分钟
const ONE_HOUR = 3600; // 1小时
const ONE_DAT = 86400; // 1天
const THREE_DAT = 259200; // 3天
const SEVEN_DAT = 604800; // 7天
const THIRTY_DAT = 2592000; // 30天
}
\ No newline at end of file
<?php
namespace Helpers;
/**
* AES 加密 解密类库
*/
class Aes {
/**
* 加密
* @param String content 加密的字符串
* @return string|string[]
*/
public static function encrypt($content = '') {
$key = appConfig('aes.key');
$iv = appConfig('aes.iv');
$data = openssl_encrypt($content, "AES-128-CBC", $key, 0, $iv);
return self::urlsafeEncrypt($data);
}
/**
* 解密
* @param String content 解密的字符串
* @return String
*/
public static function decrypt($content) {
$content = self::urlsafeDecrypt($content);
$key = appConfig('aes.key');
$iv = appConfig('aes.iv');
return openssl_decrypt($content, "AES-128-CBC", $key, 0, $iv);
}
public static function urlsafeEncrypt($string) {
return str_replace(array('+','/','='), array('-','_',''), $string);
}
public static function urlsafeDecrypt($string) {
$string = str_replace(array('-','_'), array('+','/'), $string);
$mod4 = strlen($string) % 4;
if ($mod4) {
$string .= substr('====', $mod4);
}
return $string;
}
// openssl AES 向量长度固定 16 位 这里为兼容建议固定长度为 16 位
// 随机字符串
public static function getRandomStr($length = 16) {
$char_set = array_merge(range('a', 'z'), range('A', 'Z'), range('0', '9'));
shuffle($char_set);
return implode('', array_slice($char_set, 0, $length));
}
/**
* 生成每次请求的sign
* @param array $data
* @return string
*/
public static function createSign($data = []) {
// 1 按字段排序
ksort($data);
// 2拼接字符串数据 &
$string = http_build_query($data);
// 3通过aes来加密
$string = self::encrypt($string);
return $string;
}
/**
* 检查sign是否正常
* @param array $data
* @param $data
* @return bool
*/
public static function checkSign($data) {
if(!isset($data['sign'])
|| empty($data['sign'])
|| !isset($data['reqid'])
|| !isset($data['appid'])
|| !isset($data['platform'])
) {
return false;
}
$str = self::decrypt($data['sign']);
if(empty($str)) {
return false;
}
// appid=xx&version=023300&....
parse_str($str, $arr);
if(!is_array($arr)
|| !isset($arr['reqid'])
|| !isset($arr['appid'])
|| !isset($arr['platform'])
|| $arr['reqid'] != $data['reqid']
|| $arr['appid'] != $data['appid']
|| $arr['platform'] != $data['platform']
) {
return false;
}
$timeout = appConfig('aes.timeout');
$switch = appConfig('aes.switch');
if($switch) {
if ((time() - ceil($arr['ts'] / 1000)) > $timeout) {
return false;
}
}
return true;
}
}
\ No newline at end of file
<?php
namespace Helpers;
trait ApiResponse
{
/**
* 成功返回格式
*
* @param array $data
* @param string $status
* @param array $headers
* $headers['content-type'] = 'application/json'
* @return void
* @throws \Exception
*/
public function success($data = [], $status = "success", $headers = [])
{
$this->respond(0, $status, '', $data, $headers);
}
/**
* 失败返回格式,有失败原因
*
* @param [type] $code
* @param string $reason
* @param array $headers
* @return void
* @throws \Exception
*/
public function failed($code, $reason = '', $status = "failed", $headers = [])
{
$this->respond($code, $status, $reason, [], $headers);
}
public function respond($code, $status, $reason, array $data = [], $headers = [])
{
$resp = [
'code' => $code,
'status' => $status
];
if ($reason) {
$resp['reason'] = $reason;
}
if ($data && ! is_array($data)) {
$data = json_decode(strval($data), true);
if ($data === NULL) {
throw new \Exception('非json格式', 13);
}
}
$response = \Yaf\Dispatcher::getInstance()->getResponse();
$response->setHeader('content-type', 'application/json');
if ($data) {
$apiHeader = "";
if (isset($data['code'])) {
$apiHeader = $apiHeader . strval($data['code']);
}
if (isset($_SESSION['userid'])) {
$apiHeader = $apiHeader . "_" . strval($_SESSION['userid']);
}
if (strlen($apiHeader) > 0) {
$response->setHeader('Api-Result', $apiHeader);
}
}
// headder中输出主要依赖服务的处理时间
if (isset($GLOBALS['DEPENDENT-REQUEST-TIME'])) {
$response->setHeader('Dependent-Request-Time', $GLOBALS['DEPENDENT-REQUEST-TIME']);
}
if (isset($GLOBALS['DEPENDENT-STATUS'])) {
$response->setHeader('Dependent-Status', $GLOBALS['DEPENDENT-STATUS']);
}
if (isset($GLOBALS['DEPENDENT-URI'])) {
$response->setHeader('Actual-Request-Url', $GLOBALS['DEPENDENT-URI']);
}
if ($headers) {
foreach ($headers as $name => $value) {
$response->setHeader($name, $value);
}
}
$data = array_merge($resp, $data);
$response->setBody(json_encode($data, JSON_UNESCAPED_UNICODE));
$response->response();
if (function_exists('fastcgi_finish_request')) {
ignore_user_abort(true);
fastcgi_finish_request();
}
}
}
\ No newline at end of file
<?php
/**
* 调试日志操作类
* DEBUG_LEVEL=0的时候不会在后端运行,
* DEBUG_LEVEL=1的时候会记录错误、警告信息以及资源调用的耗时汇总统计,
* DEBUG_LEVEL=2的时候,会记录全部的数据
* 如果在参数列表中出现 __DEBUG_LEVEL ,则会强制覆盖 DEBUG_LEVEL 的值
* 功能列表如下:
* 1 time 性能探针,计算运行的步骤以及每一步的执行效率
* 2 log 日志记录,把每一个日志信息记录下来
* 3 http 接口调用的记录以及耗时的汇总统计
* 4 redis redis调用的记录以及耗时的汇总统计
* 5 mysql mysql调用的记录以及耗时的汇总统计
* 6 cache memcache调用的记录以及耗时的汇总统计
*/
namespace Helpers;
define('DEBUG_LOG_ERROR', 'ERROR');
define('DEBUG_LOG_WARNING', 'WARNING');
define('DEBUG_LOG_INFO', 'INFO');
class DebugLog {
private $logId;
private $timeList;
private $logList;
private $httpList;
private $redisList;
private $mysqlList;
private $cacheList;
private static $instance = false;
private function __construct() {}
/**
* 初始化调试日志操作类,没有经过初始化的后续调试代码都不会生效
*/
public static function init() {
if (!self::$instance) {
self::$instance = new DebugLog();
self::$instance->logId = microtime();
}
}
/**
* 记录时间,方便调试程序执行逻辑和每一步的执行效率
*/
public static function time($label, $handler = false) {
if (self::$instance === false) {
return;
}
self::$instance->timeList[] = array($label, microtime(), $handler);
}
/**
* 记录运行时的调试信息,分为 DEBUG_LOG_INFO 和 DEBUG_LOG_ERROR,DEBUG_LOG_INFO 只有在全量输出调试信息的时候才会输出
*/
public static function log($label, $info, $level=DEBUG_LOG_INFO, $handler = false) {
if (self::$instance === false || (DEBUG_LEVEL < 2 && $level == DEBUG_LOG_INFO)) {
return;
}
self::$instance->logList[] = array($label, $info, $level, $handler);
}
/**
* 记录运行时的http请求
*/
public static function http($label, $params, $config, $mtime1, $mtime2, $data = null, $handler = false) {
if (self::$instance === false) {
return;
}
if (DEBUG_LEVEL === 1) {
self::$instance->httpList[] = array($label, json_encode($params), json_encode($config), $mtime1, $mtime2, null, $handler);
} else {
self::$instance->httpList[] = array($label, json_encode($params), json_encode($config), $mtime1, $mtime2, $data, $handler);
}
}
/**
* 记录运行时的redis请求
*/
public static function redis($label, $params, $config, $mtime1, $mtime2, $data = null, $handler = false) {
if (self::$instance === false) {
return;
}
if (DEBUG_LEVEL === 1) {
if ('setex' == $label) { // 过滤掉内容块,避免日志太多
$params[2] = null;
}
self::$instance->redisList[] = array($label, json_encode($params), json_encode($config), $mtime1, $mtime2, null, $handler);
} else {
self::$instance->redisList[] = array($label, json_encode($params), json_encode($config), $mtime1, $mtime2, $data, $handler);
}
}
/**
* 记录运行时的mysql请求
*/
public static function mysql($label, $params, $config, $mtime1, $mtime2, $data = null, $handler = false) {
if (self::$instance === false) {
return;
}
if (DEBUG_LEVEL === 1) {
self::$instance->mysqlList[] = array($label, json_encode($params), json_encode($config), $mtime1, $mtime2, null, $handler);
} else {
self::$instance->mysqlList[] = array($label, json_encode($params), json_encode($config), $mtime1, $mtime2, $data, $handler);
}
}
/**
* 记录运行时的memcache请求
*/
public static function cache($label, $params, $config, $mtime1, $mtime2, $data = null, $handler = false) {
if (self::$instance === false) {
return;
}
if (DEBUG_LEVEL === 1) {
self::$instance->cacheList[] = array($label, json_encode($params), json_encode($config), $mtime1, $mtime2, null, $handler);
} else {
self::$instance->cacheList[] = array($label, json_encode($params), json_encode($config), $mtime1, $mtime2, $data, $handler);
}
}
/**
* 输出日志
*/
public static function show() {
if (self::$instance === false) {
return;
}
if (isset($_SERVER['HTTP_USER_AGENT'])) {
// 界面上可视化模式输出内容
self::$instance->showViews();
} else {
self::$instance->writeLogs();
}
}
/**
* 是否有可视化界面输出,HTML代码直接返回到浏览器
*/
public static function is_show_view() {
if (self::$instance && isset($_SERVER['HTTP_USER_AGENT'])) {
return true;
} else {
return false;
}
}
/**
* 将microtime的时间字符串转换为float型的毫秒时间
*/
private function floatMicrotime($mt) {
if (strpos($mt, ' ')) {
list($ms, $m) = explode(' ', $mt);
return ($m + $ms) * 1000;
} else {
return floatval($mt) * 1000;
}
}
/**
* 计算两个microtime时间的间隔时间
* @param $m1 开始时间
* @param $m2 结束时间
* @param $round 保留小数位
*/
private function intervalTime($m1, $m2, $round = 3) {
return round(($this->floatMicrotime($m2) - $this->floatMicrotime($m1)), $round);
}
/**
* 将调试信息生成可视化的HTML代码
*/
private function showViews() {
$showTime = microtime();
$output = array();
$output[] = "\n";
$output[] = '<ul>';
$output[] = '<li><strong style="font-size:18px;">DebugLog showViews.total process time is ' . $this->intervalTime($this->logId, $showTime) . 'ms</strong></li>';
if ($this->timeList) {
$total_num = count($this->timeList);
$output[] = '<li><strong style="font-size:18px;">TimeList total count is ' . count($this->timeList) . ', log time is ' . $this->intervalTime($this->logId, $this->timeList[$total_num - 1][1]) . '</strong></li>';
$lasttime = $this->logId;
$output[] = '<li>0.000 : start debug log ' . $lasttime . '</li>';
foreach ($this->timeList as $info) {
$lasttime2 = $info[1];
$output[] = '<li>'. $this->intervalTime($lasttime, $lasttime2) . ' : ' . implode("\t", $info) . '</li>';
$lasttime = $lasttime2;
}
}
if ($this->logList) {
$output[] = '<li><strong style="font-size:18px;">LogList total count is ' . count($this->logList) . '</strong></li>';
foreach ($this->logList as $info) {
$output[] = '<li>' . implode("\t", $info) . '</li>';
}
}
if ($this->httpList) {
$current = count($output);
$total_time = 0;
$output[] = null;
$max_num = array();
$multi_num = array();
foreach ($this->httpList as $info) {
$intval = $this->intervalTime($info[3], $info[4]);
$multi_flag = @json_decode($info[2],true);
if(isset($multi_flag) && isset($multi_flag['is_multi']) && $multi_flag['is_multi']==1)
{
$multi_str = strval($multi_flag['multi_num']);
if($intval > $max_num[$multi_str])
{
$max_num[$multi_str] = $intval;
if(!in_array($multi_str, $multi_num))
{
$multi_num[] = $multi_str;
}
}
}
else
{
$total_time += $intval;
}
if ($info[5] && is_array($info[5])) {
$info[5] = json_encode($info[5]);
}
$output[] = '<li>'. $intval .' : ' . implode("\t", $info) . '</li>';
}
if(!empty($multi_num ))
{
foreach($multi_num as $val)
{
$total_time += $max_num[$val];
}
}
$output[$current] = '<li><strong style="font-size:18px;">HttpList total count is ' . count($this->httpList) . ', total time is ' . $total_time . '</strong></li>';
}
if ($this->redisList) {
$current = count($output);
$total_time = 0;
$output[] = null;
foreach ($this->redisList as $info) {
$intval = $this->intervalTime($info[3], $info[4]);
$total_time += $intval;
if ($info[5] && is_array($info[5])) {
$info[5] = json_encode($info[5]);
}
$output[] = '<li>'. $intval .' : ' . implode("\t", $info) . '</li>';
}
$output[$current] = '<li><strong style="font-size:18px;">RedisList total count is ' . count($this->redisList) . ', total time is ' . $total_time . '</strong></li>';
}
if ($this->mysqlList) {
$current = count($output);
$total_time = 0;
$output[] = null;
foreach ($this->mysqlList as $info) {
$intval = $this->intervalTime($info[3], $info[4]);
$total_time += $intval;
if ($info[5] && is_array($info[5])) {
$info[5] = json_encode($info[5]);
} elseif (!$info[5]) {
$info[5] = '';
}
$output[] = '<li>'. $intval .' : ' . implode("\t", $info) . '</li>';
}
$output[$current] = '<li><strong style="font-size:18px;">MysqlList total count is ' . count($this->mysqlList) . ', total time is ' . $total_time . '</strong></li>';
}
if ($this->cacheList) {
$current = count($output);
$total_time = 0;
$output[] = null;
foreach ($this->cacheList as $info) {
$intval = $this->intervalTime($info[3], $info[4]);
$total_time += $intval;
if ($info[5] && is_array($info[5])) {
$info[5] = json_encode($info[5]);
}
$output[] = '<li>'. $intval .' : ' . implode("\t", $info) . '</li>';
}
$output[$current] = '<li><strong style="font-size:18px;">CacheList total count is ' . count($this->cacheList) . ', total time is ' . $total_time . '</strong></li>';
}
$output[] = '</ul>';
echo implode("\n", $output);
}
/**
* 将调试日志写入到本地文件中,使用JSON格式保存为一行
*/
public function writeLogs() {
$showTime = microtime();
if (!defined('DEBUG_LOG_PATH')) {
define('DEBUG_LOG_PATH', '/var/log/');
}
$serverList = array(
'SCRIPT_NAME' => $_SERVER['SCRIPT_NAME'],
'REQUEST_URI' => $_SERVER['REQUEST_URI'],
'REMOTE_ADDR:PORT' => $_SERVER['REMOTE_ADDR'] . ':' . $_SERVER['REMOTE_PORT'],
);
$datalist = array(
'logId'=>$this->logId,
'logTime'=>$showTime,
'timeList'=>$this->timeList,
'logList'=>$this->logList,
'httpList'=>$this->httpList,
'redisList'=>$this->redisList,
'mysqlList'=>$this->mysqlList,
'server'=>$serverList,
);
$str = json_encode($datalist);
$str = str_replace("\n", ' ', $str);
$str .= "\n";
$file_path = DEBUG_LOG_PATH . 'custum_debug.log';
if($fd = @fopen($file_path, 'a')) {
fputs($fd, $str);
fclose($fd);
}
}
/**
* 将消息输出到指定的文件
* 默认 define('DEBUG_LOG_PATH', '/home/worker/log/php/today/')
* @param $msg 消息内容
* @param string $file 日志文件名称,默认是 custum_debug.log
*/
public static function writeDebugLog($msg, $file='custum_debug.log') {
$dtime = date('Y-m-d H:i:s');
if (!defined('DEBUG_LOG_PATH')) {
$default_path = '/var/log/';
if (file_exists($default_path)) {
define('DEBUG_LOG_PATH', $default_path);
} else {
define('DEBUG_LOG_PATH', '');
}
}
// $str_cookie = json_encode($_COOKIE);
$str_cookie = 'no cookie';
$str_server = json_encode(array($_SERVER['HTTP_X_FORWARDED_FOR'], $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI']));
$str = "[$dtime]||$msg||$str_cookie||$str_server\n";
$file_path = DEBUG_LOG_PATH . $file;
if($fd = @fopen($file_path, 'a')) {
fputs($fd, $str);
fclose($fd);
}
}
/**
* 通过PHP的 debug_backtrace 可以详细的查看到方法调用的细节情况
*/
public static function writeBacktrace($deep=3, $all=false) {
$result = array();
$trace = debug_backtrace();
unset($trace[0]);
if ($deep < count($trace)) {
for ($i = 1; $i <= $deep; $i++) {
$info = $trace[$i];
if (isset($info['object']) && $all === false) {
unset($info['object']);
}
$result[] = $info;
}
} elseif ($all === false) {
foreach ($trace as $info) {
if (isset($info['object'])) {
unset($info['object']);
}
$result[] = $info;
}
} else {
$result = $trace;
}
self::writeDebugLog(json_encode($result), 'backtrace.log');
}
}
<?php
namespace Validate;
use Api\PhpUtils\Validate\Validate;
use App\Exception\custom\Code;
use App\Exception\custom\ParamException;
use Yaf\Dispatcher;
class BaseValidate extends Validate
{
/**
* 参数校验
* @return array | boolean
* @throws
*/
public function validate()
{
$params = Dispatcher::getInstance()->getRequest()->getRequest();
$result = $this->batch()->check($params);
if (!$result) {
$msg = $this->getError() ? array_shift($this->error) : "参数错误";
throw new ParamException([
'msg' => $msg,
"code" => Code::PARAM
]);
} else {
return true;
}
}
protected function isPositiveInteger($value)
{
if (is_numeric($value) && is_int($value + 0) && ($value + 0) > 0) {
return true;
} else {
return false;
}
}
protected function isMobile($value)
{
$rule = '^1(3|4|5|7|8)[0-9]\d{8}$^';
$result = preg_match($rule, $value);
if ($result) {
return true;
} else {
return false;
}
}
protected function idcard($value){
$weight = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
$codes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
if(strlen($value)!=18){
return false;
}
$validate = substr($value, 0, 17);
$sum = 0;
for ($i = 0; $i < 17; $i++) {
$sum += $validate[$i] * $weight[$i];
}
return $codes[$sum % 11] === substr($value, 17, 1);
}
}
\ No newline at end of file
<?php
namespace Validate;
class TestValidate extends BaseValidate
{
/**
* @var array
* 基础规则
* 可以自定义方法,比如 checkIDs
* 可以使用系统已定义的验证规则,在 Validate 基类的 $typeMsg 中查看
*/
protected $rule = [
'ids' => 'checkIDs',
'email' => 'email',
'age' => 'between:0,100',
];
/**
* 自定义某一规则不符合后,输出给用户的提示语
* @var string[]
*/
protected $message = [
"ids.require" => "ids 参数必填",
"ids.checkIDs" => "ids 格式有误",
"email.email" => "邮箱格式有误",
];
/**
* 场景定义
* edit 场景仅需要验证 email 与 age,并且不需要增加或删除验证条件
* @var \string[][]
*/
protected $scene = [
'edit' => ['email','age'],
];
/**
* 场景定义2
* 定义一个方法,scene 做前缀,驼峰的加上场景名
* only 定义需要验证的参数
* append 在 rule 定义的条件基础上,再增加其他验证条件
* remove 删除在 rule 中定义的某条件
* @return TestValidate
*/
public function sceneAdd()
{
return $this->only(['ids','email','age'])
->append('ids', 'require')
->append('email', 'require');
}
protected function checkIDs($params)
{
//id字符串转为id数组
$params = explode(',', $params);
if (empty($params)) {
return false;
}
//每个id只能由字母数字组成
foreach ($params as $param) {
if (!$this->regex($param, '/^[A-Za-z0-9]+$/')) {
return false;
}
}
return true;
}
}
\ No newline at end of file
<?php
namespace Validate;
class UserPhoneValidate extends BaseValidate
{
protected $rule = [
'user_id' => 'require',
'mobile' => 'require|isMobile'
];
protected $message = [
"user_id" => "用户信息获取失败",
"mobile" => "手机号格式错误"
];
}
\ No newline at end of file
<?php
namespace Validate;
class UseridValidate extends BaseValidate
{
protected $rule = [
'user_id' => 'require'
];
protected $message = [
"user_id" => "用户信息获取失败"
];
}
\ No newline at end of file
<?php
use Yaf\Application;
use Yaf\Dispatcher;
if (!function_exists('config')) {
/**
* 假设当前环境为 dev(在php.ini中配置)
* 当前 appid 为 ProgramA (在conf/application.ini中配置)
* 则 config("test", "a"); 将取到 yaconf/test.ini 中, [dev-ProgramA] 下定义的配置 a 的值
*
* @param $file
* @param string $param
* @return string
*/
function config($file, $param = ''){
if (empty($file) || !file_exists(ROOT_PATH."/yaconf/".$file.".ini")){
return "";
}
$env = Application::app()->environ() ?? "test";
$appid = Application::app()->getConfig()->get("appid");
$key = $file.'.'. (empty($appid) ? $env : $env.'-'.$appid);
$key = $param ==='' ? $key : $key.".".$param;
return \Yaconf::get($key);
}
if (!function_exists('appConfig')) {
/**
* 获取框架的 conf/application 中的配置
* @param $param
* @return mixed
*/
function appConfig($param){
return Application::app()->getConfig()->get($param);
}
}
if (!function_exists('getHeader')) {
function getHeader($name = null){
if($name){
return Dispatcher::getInstance()->getRequest()->getServer(strtoupper('HTTP_'.$name));
}
return Dispatcher::getInstance()->getRequest()->getServer();
}
}
if (!function_exists('page')) {
function page($param){
$page_start = 0;
$page_size = 20;
if(isset($param['page_size']) && $param['page_size']>0){
$page_size = intval($param['page_size']);
}
if (isset($param['page']) && $param['page']>0){
$page_start = (intval($param['page']) - 1) * $page_size;
}
return [
'start' => $page_start,
'size' => $page_size
];
}
}
if (!function_exists('filterArrByField')) {
/**
* 过滤数组,只留 $field 中的字段
* @param $array array
* @param $field array
* @return array
*/
function filterArrayByField(array $array, array $field, $recursive = true){
if(empty($field) || empty($array)){
return $array;
}
foreach ( $array as $key => $val ) {
if( $recursive && is_array($val)){
$array[$key] = filterArrayByField($val, $field);
} elseif(!in_array($key."", $field)){
unset($array[$key]);
}
}
return $array;
}
}
if (!function_exists('arrayGroupBy')) {
/**
* 二维数组转三维数组(指定键为三维数组的键名)
*
* @param [type] $arr [要排序的数组]
* @param [type] $key [指定的键]
* @return [type] $grouped [重排的数组]
*/
function arrayGroupBy($arr, $key)
{
$grouped = [];
foreach ($arr as $value) {
$grouped[$value[$key]][] = $value;
}
if (func_num_args() > 2) {
$args = func_get_args();
foreach ($grouped as $key => $value) {
$parms = array_merge([$value], array_slice($args, 2, func_num_args()));
$grouped[$key] = call_user_func_array('array_group_by', $parms);
}
}
return $grouped;
}
}
}
\ No newline at end of file
## library
#### 全局的处理函数请在heapler.php中编写
#### 验证器,工具类,其他类库请新建目录,指定命名空间,细节参考已有的类库文件
<?php
namespace App\Models;
/**
* Class Dictionary
* @package App\Models
* 项目通用字典及文案
*/
class Dictionary
{
public const O_PAY_STATUS_UNPAY = 0; //未支付
public const O_PAY_STATUS_WAIT = 1; //待确认
public const O_PAY_STATUS_PAYED = 2; //已支付
public const YES = 1; //是
public const NO = 0; //否
public const CHANNEL_WX = 1; //wx
public const CHANNEL_WX_PUB = 2; //wx_pub
public const CHANNEL_WX_LITE = 3; //wx_lite
public const CHANNEL_WX_ALIPAY = 10; //alipay
public const SOURCE_LIFE = 1; //生活圈
public const SOURCE_MAIN = 2; //主端
}
<?php
namespace App\Models\demo\mongo;
use Api\PhpUtils\Mongo\MongoBase;
class Test extends MongoBase
{
protected function getConfigIndex()
{
return "demo";
}
protected function getDatabaseName()
{
return "demo";
}
protected function getCollectionName()
{
return "user";
}
protected function getWhere($params)
{
return $params;
}
protected function getQueryOptions($fields = [], $sort = [], $limit = [])
{
$options = [
'maxTimeMS' => 800,
'limit' => 100
];
if (is_array($fields) && !empty($fields)) {
$options['projection'] = $fields;
}
if (is_array($sort) && !empty($sort)) {
$options['sort'] = $sort;
}
if (is_array($limit)) {
if (isset($limit['start'])) {
$options['skip'] = intval($limit['start']);
}
if (isset($limit['count'])) {
$options['limit'] = intval($limit['count']);
}
}
return $options;
}
}
<?php
namespace App\Models\demo\mongo;
use Api\PhpUtils\Mongo\Base;
class User extends Base
{
protected static $instance;
protected static $db_config_index = 'metro';
protected function getCollectionName()
{
return 'user';
}
protected function getWhere($params)
{
$where = [];
if (isset($params['name']) && !empty($params['name'])) {
$where['name'] = $params['name'];
}
return $where;
}
protected function getQueryOptions()
{
$options = [
'projection' => [
'mobile' => 1
],
'maxTimeMS' => 800,
'limit' => 5,
'sort' => ['mobile' => -1]
];
return $options;
}
}
<?php
namespace App\Models\demo\mysql;
use Api\PhpUtils\Mysql\MysqlBase2;
class TestMysql extends MysqlBase2
{
const TABLE_NAME = 'test';
const CONFIG_INDEX = 'merchant';
const LIFE_ACCOUNT_TYPE_PERSIONAL = 1; // 个人
const LIFE_ACCOUNT_TYPE_ENTERPRISE = 2; // 企业
const LIFE_ACCOUNT_STATUS_ON = 1; // 上线
const LIFE_ACCOUNT_STATUS_OFF = 2; // 下线
const LIFE_ACCOUNT_STATUS_UPGRADE = 3; // 升级中
const LIFE_ACCOUNT_AUTH_STATUS_NO = 1; // 未认证生活号
const LIFE_ACCOUNT_AUTH_STATUS_YES = 2; // 已认证生活号
const ENTERPRISE_AUTH_STATUS_ING = 1; // 升级审核中
const ENTERPRISE_AUTH_STATUS_FAIL = 2; // 升级失败
public static function getRecord($where, $colums = [])
{
if (empty($colums)) {
$colums = '*';
}
return self::get($colums, $where);
}
public static function getRecordMaster($where, $colums = [])
{
if (empty($colums)) {
$colums = '*';
}
return self::selectMaster($colums, $where);
}
public static function insertRecord($colums)
{
return self::insert($colums);
}
public static function updateRecord($colums, $where)
{
return self::update($colums, $where);
}
public static function save($data, $where = [])
{
if (empty($where)) {
return self::insert($data);
}
return self::update($data, $where);
}
public static function deleteRecord($where)
{
return self::delete($where);
}
public static function getAccountList($data, $colums = [])
{
$colums = " * ";
$where = " 1=1 ";
if (!empty($data['life_account_name'])) {
$where .= " and (`life_account_name` LIKE '%{$data['life_account_name']}%') ";
}
if (!empty($data['life_account_type'])) {
$where .= " and life_account_type = '{$data['life_account_type']}'";
}
if (!empty($data['ORDER'])) {
$where .= " ORDER BY `create_time` DESC ";
}
if (!empty($data['LIMIT'])) {
$where .= " LIMIT {$data['LIMIT'][1]} OFFSET {$data['LIMIT'][0]} ";
}
return $data = self::query("SELECT {$colums} FROM `life_account` WHERE $where ")->fetchAll();
}
public static function getAccountCount($data, $colums = [])
{
$colums = " * ";
$where = " 1=1 ";
if (!empty($data['life_account_name'])) {
$where .= " and (`life_account_name` LIKE '%{$data['life_account_name']}%') ";
}
if (!empty($data['life_account_type'])) {
$where .= " and life_account_type = '{$data['life_account_type']}'";
}
$data = self::query("SELECT COUNT(*) as count FROM `life_account` WHERE $where ")->fetch();
return !empty($data['count']) ? $data['count'] : 0;
}
public static function getRecords($where, $colums = [])
{
if (empty($colums)) {
$colums = '*';
}
return self::select($colums, $where);
}
public static function getCount($where)
{
return self::count($where);
}
public static function duplicate($data, $duplicate)
{
return self::insertDuplicate($data, $duplicate);
}
public static function forupdate($columns, $where)
{
return self::selectForUpdate($columns, $where);
}
}
<?php
namespace App\Models\demo\mysql;
use Api\PhpUtils\Mysql\Base;
class User extends Base
{
protected static $write;
protected static $read;
protected static $db_config_index = 'metro';
protected function getTableName()
{
return 'user';
}
protected function getPKey()
{
return 'id';
}
protected function getWhere($params)
{
$where = [];
if (isset($params['ids']) && !empty($params['ids'])) {
$where['id'] = $params['ids'];
}
if (isset($params['name']) && !empty($params['name'])) {
$where['name'] = $params['name'];
}
if (isset($params['id[>]']) && !empty($params['id[>]'])) {
$where['id[>]'] = $params['id[>]'];
}
return $where;
}
}
<?php
namespace App\Models\order\mysql;
use Api\PhpUtils\Mysql\MysqlBase;
class PayOrder extends MysqlBase
{
protected static $write;
protected static $read;
protected static $db_config_index = 'metro';
protected function getTableName()
{
return 'pay_order';
}
protected function getPKey()
{
return 'pay_order_id';
}
public function selectForUpdate($id) {
$link = self::getConnection('write');
$link->pdo->
}
}
<?php
namespace App\Models\order\mysql;
use Api\PhpUtils\Mysql\Base;
class PayOrderClearing extends MysqlBase
{
protected static $write;
protected static $read;
protected static $db_config_index = 'metro';
protected function getTableName()
{
return 'pay_order_clearing';
}
protected function getPKey()
{
return 'pay_order_clearing_id';
}
}
<?php
namespace App\Models\order\mysql;
use Api\PhpUtils\Mysql\Base;
class PayOrderClearingItem extends MysqlBase
{
protected static $write;
protected static $read;
protected static $db_config_index = 'metro';
protected function getTableName()
{
return 'pay_order_clearing_item';
}
protected function getPKey()
{
return 'pay_order_clearing_item_id';
}
}
<?php
namespace App\Models\order\mysql;
use Api\PhpUtils\Mysql\Base;
class RefundOrder extends MysqlBase
{
protected static $write;
protected static $read;
protected static $db_config_index = 'metro';
protected function getTableName()
{
return 'refund_order';
}
protected function getPKey()
{
return 'refund_order_id';
}
}
## Models
#### 已有的demo请在开发时删除
<?php
namespace App\Base;
use Helpers\ApiResponse;
use Yaf\Controller_Abstract;
abstract class Base extends Controller_Abstract
{
use ApiResponse;
/**
* 前置操作方法列表
*
* protected $beforeActionList = [
* 'first', //在所有方法前执行
* 'second' => ['except'=>'hello'], //在除了hello以外的其它方法之前执行
* 'three' => ['only'=>'hello,data'] //只在hello,data方法前执行
* ];
*
* @var array $beforeActionList
* @access protected
*/
protected $beforeActionList = [];
/**
* @var mixed
*/
protected $params;
public function init(){
$this->setParam();
// 前置操作方法
if (!empty($this->beforeActionList)) {
foreach ($this->beforeActionList as $method => $options) {
is_numeric($method) ? $this->beforeAction($options) : $this->beforeAction($method, $options);
}
}
}
/**
* 前置操作
* @access protected
* @param string $method 前置操作方法名
* @param array $options 调用参数 ['only'=>[...]] 或者['except'=>[...]]
*/
private function beforeAction($method, $options = [])
{
$action = $this->getRequest()->getActionName();
if (isset($options['only'])) {
if (is_string($options['only'])) {
$options['only'] = explode(',', $options['only']);
}
if (!in_array($action, $options['only'])) {
return;
}
} elseif (isset($options['except'])) {
if (is_string($options['except'])) {
$options['except'] = explode(',', $options['except']);
}
if (in_array($action, $options['except'])) {
return;
}
}
call_user_func([$this, $method]);
}
private function setParam(){
$params = $this->getRequest()->getRequest();
unset($params['s']);
$this->params = $params;
}
}
<?php
namespace App\Base;
use Yaf\Controller_Abstract;
class Cli extends Controller_Abstract
{
public function init() {
\Yaf\Dispatcher::getInstance()->disableView();
}
}
\ No newline at end of file
<?php
use Api\PhpServices\Daemon\Daemon;
use App\Base\Cli;
use Yaf\Application;
/**
* 守护进程入口脚本
* conf/cli.ini 中配置脚本目录,默认在 /daemon
* 脚本必须继承 DaemonServiceInterface,参考 daemon/Test.php
* 以守护进程方式执行 Test 脚本命令参考:php public/cli.php daemon run "t=Test&n=2&j=abc"
* t : 脚本类名
* n : 进程数
* j : 进程别名,默认为脚本类名
*/
class DaemonController extends Cli
{
public function RunAction(){
$request = $this->getRequest();
$params = $request->getParams();
$task_name = $params['t'] ?? "";
$worker_num = $params['n'] ?? 4;
$rename = $params['j'] ?? $task_name;
if(empty($task_name)){
echo <<<EOD
usage: php cli.php daemon run "t=[string]&n=[int|default:4]&j=[string]"
t daemo 脚本类名
n 进程数
j 进程别名,默认同脚本类名
stop : kill -SIGUSR1 master进程id\n
EOD;
return;
}
$script_dir = Application::app()->getConfig()->get("daemon.script_dir");
$task_class = $script_dir.$task_name;
if(!class_exists($task_class)){
die("脚本不存在!");
}
$check = new ReflectionClass($task_class);
if(!$check->implementsInterface('Api\PhpServices\Daemon\DaemonServiceInterface')){
die("脚本需实现 DaemonServiceInterface 接口!");
}
(new Daemon($rename, $task_class, $worker_num))->start();
}
}
\ No newline at end of file
<?php
use App\Base\Cli;
class TestController extends Cli
{
public function IndexAction() {
$request = $this->getRequest();
$params = $request->getParams();
$res = [
"data" => $params,
"code" => 0
];
$response = $this->getResponse();
$response->setBody(json_encode($res));
}
}
\ No newline at end of file
<?php
use App\Base\Base;
use App\Exception\custom\LifeAccountException;
use App\Exception\custom\LifeAccountRoleException;
use App\Models\auth\mysql\Merchant;
use App\Models\auth\mysql\LifeAccountRole;
use App\Services\lifeaccount\LifeAccountService;
use Validate\UserPhoneValidate;
use App\Models\auth\mysql\LifeAccount;
use App\Exception\custom\MerchantException;
use App\Exception\custom\AuthException;
use Helpers\Aes;
use Api\PhpUtils\Http\Request;
use App\Exception\custom\DataException;
use App\Models\auth\mysql\PersionalAuthRecord;
use App\Models\auth\mysql\EnterpriseAuthRecord;
use Api\PhpUtils\Cache\CacheUtil;
use Api\PhpUtils\Redis\RedisUtil;
use Api\PhpUtils\Log\FileLog;
class AccountController extends Base
{
/**
* 创建未认证的个人生活号
*/
public function create_unauthorizedAction()
{
// 获取手机号
(new UserPhoneValidate())->validate();
$params = $this->params;
$uid = $params['user_id'];
$mobile = $params['mobile'];
// 查询是否有创建资格
if (!LifeAccountService::permission($uid)['personal']) {
throw new LifeAccountException(['cus' => 3]);
}
try {
Merchant::beginTransaction();
LifeAccountService::unauth_account($uid, $mobile);
Merchant::commit();
} catch (\Exception $exception) {
Merchant::rollback();
throw $exception;
}
$this->success();
}
/**
* 获取生活号详情
*
*/
public function get_account_infoAction()
{
$params = $this->params;
$data['account_id'] = $params['account_id']; //当前用户ID
$data['followed_id'] = $params['followed_id']; // 被关注用户ID
$data['account_type'] = 1;
$data['followed_type'] = 1;
//拿粉丝、关注、赞数和是否关注
$url = config('interface', 'interaction.index.life_detail');
if (empty($url)) {
throw new DataException(['cus' => 0]);
}
$res = (new Request())->get($url, $data);
var_dump($res);exit;
if ($res['code'] == 0 && isset($res['response'])) {
$this->returnResponse($res['response']);
return;
}
//获取生活号角色
$LifeAccountRole = LifeAccountRole::getRecord(['user_id' => $user_id], "*");
if ($LifeAccountRole === false || empty($LifeAccountRole)) {
throw new LifeAccountRoleException(['cus' => 7]);
}
// 查生活号与商户信息
$lifeAccountInfo = LifeAccount::get('*', ['life_account_id' => $LifeAccountRole['life_account_id']]);
if ($lifeAccountInfo === false || empty($lifeAccountInfo)) {
throw new LifeAccountException(['cus' => 2]);
}
//tab
if ($user_id == $lifeAccountInfo['life_account_admin_id']) {
//主态
$tab = array(
1 => '服务',
2 => '招聘',
3 => '发布',
4 => '参与',
5 => '推荐'
);
} else {
//客态
$tab = array(
1 => '服务',
2 => '招聘',
3 => '发布',
4 => '参与',
5 => '推荐'
);
}
$retLifeAccount['life_account_id'] = (string)$lifeAccountInfo['life_account_id'];
$retLifeAccount['life_account_name'] = $lifeAccountInfo['life_account_name'];
$retLifeAccount['life_account_icon'] = $lifeAccountInfo['life_account_icon'];
$retLifeAccount['life_account_admin_id'] = $lifeAccountInfo['life_account_admin_id'];
$retLifeAccount['life_account_auth_status'] = $lifeAccountInfo['life_account_auth_status'];
$retLifeAccount['life_account_status'] = $lifeAccountInfo['life_account_status'];
$retLifeAccount['enterprise_auth_record_status'] = $lifeAccountInfo['enterprise_auth_record_status'];
$retLifeAccount['enterprise_auth_record_id'] = $lifeAccountInfo['enterprise_auth_record_id'];
$retLifeAccount['update_time'] = $lifeAccountInfo['update_time'];
$retLifeAccount['create_time'] = $lifeAccountInfo['create_time'];
$retLifeAccount['role_type'] = $LifeAccountRole['role_type'];
$retLifeAccount['tab'] = $tab;
$this->success(['result' => $retLifeAccount]);
}
/**
* 根据生活号id获取认证信息
* 1、生活号所有字段
* 2、职业标签(个人生活号)
* 3、姓名、身份证号码、公司名称、统一社会信用代码、生活号类型(是个体还是普通企业)
*/
public function get_account_by_lidAction()
{
$params = $this->params;
$lid = $params['life_account_id'];
// 查生活号与商户信息
$lifeAccountInfo = LifeAccount::get(['life_account_id', 'life_account_name', 'life_account_type', 'merchant_id', 'life_account_admin_id', 'life_account_auth_status', 'life_account_status', 'enterprise_auth_record_id', 'update_time', 'create_time'], ['life_account_id' => $lid]);
if ($lifeAccountInfo === false || empty($lifeAccountInfo)) {
throw new LifeAccountException(['cus' => 2]);
}
// $this->cache = CacheUtil::getInstance('cache');
// $key = sprintf("life_account_info|%d",$lid);
// $redis_ret = $this->cache->set($key,json_encode($lifeAccountInfo),200);
// $redis_get = $this->cache->get($key);
//根据商户id 查询个人认证记录id
$merchant = Merchant::get(['owner_id', 'merchant_type'], ['merchant_id' => $lifeAccountInfo['merchant_id']]);
if ($merchant === false || empty($merchant)) {
throw new MerchantException(['cus' => 3]);
}
if ($lifeAccountInfo['enterprise_auth_record_id'] == 0) {
//个人生活号
if ($merchant['merchant_type'] == 1) {
$where = ['user_id' => $merchant['owner_id']];
} else {
$where = ['persional_auth_record_id' => $merchant['owner_id']];
}
//根据个人认证记录id查询个人认证详情
$personalInfo = PersionalAuthRecord::get(['full_name', 'occupation', 'id_card'], $where);
if ($personalInfo === false || empty($personalInfo)) {
throw new AuthException(['cus' => 23]);
}
$lifeAccountInfo['legal_person'] = $personalInfo['full_name'];
$lifeAccountInfo['occupation'] = $personalInfo['occupation'];
$lifeAccountInfo['id_card'] = Aes::decrypt($personalInfo['id_card']);
$lifeAccountInfo['id_type'] = 0; //个人
} else {
//企业生活号
$enterpriseInfo = EnterpriseAuthRecord::get(['legal_person', 'code', 'legal_id_card', 'name', 'data_type', 'audit_status', 'mobile'], ['life_account_id' => $lid]);
if ($enterpriseInfo === false || empty($enterpriseInfo)) {
throw new AuthException(['cus' => 23]);
}
$lifeAccountInfo['legal_person'] = $enterpriseInfo['legal_person'];
$lifeAccountInfo['code'] = $enterpriseInfo['code'];
$lifeAccountInfo['name'] = $enterpriseInfo['name'];
$lifeAccountInfo['audit_status'] = $enterpriseInfo['audit_status'];
$lifeAccountInfo['mobile'] = $enterpriseInfo['mobile'];
$lifeAccountInfo['id_type'] = $enterpriseInfo['data_type'] == 1 ? 1 : 2; //2:个体工商户; 3:普通企业
$lifeAccountInfo['id_card'] = Aes::decrypt($enterpriseInfo['legal_id_card']);
}
$lifeTag = LifeAccountService::getLifeAccountTag($lifeAccountInfo['life_account_id']);
$lifeAccountInfo['tag'] = $lifeTag['life_account_tag'] ?? '';
$lifeAccountInfo['life_account_id'] = (string)$lifeAccountInfo['life_account_id'];
$this->success(['result' => $lifeAccountInfo]);
}
/*
* 批量获取生活号角色表数据
*/
public function get_role_listAction()
{
$params = $this->params;
$params['page'] = !empty($params['page']) ? $params['page'] : 1;
$role_id = $params['role_id'] ?? 0;
$limit = !empty($params['page_size']) ? $params['page_size'] : 50;
$page = ($params['page'] - 1) * $limit;
$data['role_id[>]'] = $role_id;
$data['role_type'] = 1;
$data['LIMIT'] = [$page, $limit];
$list = LifeAccountRole::getRecordList($data);
//var_dump(LifeAccountRole::log());exit;
unset($data['LIMIT']);
$count = LifeAccountRole::getCount($data);
$this->success(['result' => ['data' => $list, 'count' => $count]]);
}
/*
* 批量获取管理员对应的生活号
*/
public function get_life_listAction()
{
$params = $this->params;
$list = [];
if ($params) {
$list = LifeAccountRole::getRecordList(['user_id' => $params, 'role_type' => 1], ['role_id', 'user_id', 'life_account_id']);
}
$this->success(['result' => $list]);
}
/*
* 批量获取生活号对应的管理员
*/
public function get_user_listAction()
{
$params = $this->params;
$list = [];
if ($params) {
$list = LifeAccount::getRecords(['life_account_id' => $params], ['life_account_id', 'life_account_admin_id', 'life_account_name']);
//FileLog::info('get_user_list', json_encode(LifeAccount::log()));
}
$this->success(['result' => $list]);
}
/**
* 根据uid获取生活号id
*/
public function get_lid_by_uidAction()
{
$params = $this->params;
$uid = $params['uid'];
$list = [];
if ($params) {
$list = LifeAccountRole::getRecordList(['user_id' => $uid], ['life_account_id']);
}
$this->success(['result' => $list]);
}
}
<?php
use App\Base\Base;
use App\Exception\custom\LifeAccountException;
use App\Models\auth\mysql\LifeAccount;
use App\Models\auth\mysql\Merchant;
use App\Services\lifeaccount\LifeAccountService;
use Validate\RecruitValidate;
use App\Models\auth\mysql\RecruitAccount;
use App\Exception\custom\DataException;
use App\Models\auth\mysql\EnterpriseAuthRecord;
use Api\PhpServices\JwUser\JwUser;
class RecruitController extends Base
{
/**
* 创建招聘个人生活号
*/
public function create_recruitAction(){
// 验证参数
(new RecruitValidate())->validate();
$params = $this->params;
$uid = $params['ownerId'];
$name = $params['name'];
if(!isset($uid) || !isset($name)){
//添加招聘表数据
$params['lifeAccountId'] = -1; //uid、name为空 不具备创建生活号的条件
$recruit_id = RecruitAccount::insert($params);
if (!$recruit_id) {
throw new DataException(['cus' => 1]);
}
$this->success(['result'=>['life_account_id' => -1]]);
}
// 查询是否有创建资格
if(!LifeAccountService::permission($uid)['personal']){
throw new LifeAccountException(['cus'=>3]);
}
try {
RecruitAccount::beginTransaction();
//创建未认证的生活号
$life_account_id = LifeAccountService::unauth_account($uid, $name, 0, 'merchant-c');
if (!$life_account_id) {
throw new DataException(['cus' => 1]);
}
//添加招聘表数据
$recruit_id = RecruitAccount::insert($params);
if (!$recruit_id) {
throw new DataException(['cus' => 1]);
}
RecruitAccount::commit();
} catch (\Exception $exception) {
RecruitAccount::rollback();
throw $exception;
}
$this->success(['result'=>['life_account_id' => $life_account_id]]);
}
/**
* 更新招聘个人生活号
*/
public function update_recruitAction(){
// 验证参数
(new RecruitValidate())->scene('ent')->validate();
$params = $this->params;
$uid = $params['ownerId'];
$res = RecruitAccount::update($params, ['ownerId' => $uid]);
if ($res === false) {
throw new DataException(['cus' => 1]);
}
$this->success();
}
/**
* 查看招聘个人生活号
*/
public function get_recruitAction(){
// 验证参数
(new RecruitValidate())->scene('ent')->validate();
$params = $this->params;
$uid = $params['ownerId'];
$recruit_ret = RecruitAccount::get('*', ['ownerId' => $uid]);
if (empty($recruit_ret)) {
throw new DataException(['cus' => 0]);
}
foreach($recruit_ret as $key => $val){
if($val === 'NULL'){
unset($recruit_ret[$key]);
}
}
$this->success(['result'=>$recruit_ret]);
}
/**
* 检测未绑定招聘个人生活号,并创建个人未认证生活号 并绑定
*/
public function check_recruitAction(){
$recruit_ret = RecruitAccount::select('*', ['lifeAccountId ' => 0]);
if (empty($recruit_ret)) {
throw new DataException(['cus' => 0]);
}
foreach($recruit_ret as $key => $val){
//获取简网用户信息
$jwUser = new JwUser();
$user_info = $jwUser->getUserByUserId(['user_id' => $val['ownerId']]);
$avatar = $user_info['data']['avatar'] ?? 'http://qn.jwshq.cn/profile_unknown_2019_1';
// 查询是否有创建资格
if(!LifeAccountService::permission($val['ownerId'])['personal']){
throw new LifeAccountException(['cus'=>3]);
}
try {
RecruitAccount::beginTransaction();
//查询是否有重复的生活号名称,有重复的加一个随机数
$lifeInfo = LifeAccount::getRecord(['life_account_name' => $val['name']]);
if(!empty($lifeInfo)){
$rand_num = mt_rand(0,99);
$val['name'] = $val['name'].$rand_num;
}
//创建未认证的生活号
$life_account_id = LifeAccountService::unauth_account($val['ownerId'], $val['name'], 0,'batch', $avatar);
if (!$life_account_id) {
throw new DataException(['cus' => 1]);
}
//更新招聘表数据生活号ID
$res = RecruitAccount::update(['lifeAccountId' => $life_account_id], ['ownerId' => $val['ownerId']]);
if ($res === false) {
throw new DataException(['cus' => 1]);
}
RecruitAccount::commit();
} catch (\Exception $exception) {
RecruitAccount::rollback();
throw $exception;
}
sleep(1);
}
$this->success(['result'=>['life_account_id' => $life_account_id]]);
}
}
\ No newline at end of file
<?php
use App\Base\Base;
use App\Services\demo\MongoService;
class MongoController extends Base
{
public function addAction()
{
$mongo_service = new MongoService();
$ret = $mongo_service->addUser();
var_dump($ret);
exit;
}
public function addManyAction()
{
$mongo_service = new MongoService();
$ret = $mongo_service->addManyUser();
var_dump($ret);
exit;
}
public function deleteAction()
{
$mongo_service = new MongoService();
$ret = $mongo_service->deleteUser();
var_dump($ret);
exit;
}
public function updateAction()
{
$mongo_service = new MongoService();
$ret = $mongo_service->updateUser();
var_dump($ret);
exit;
}
public function getAction()
{
$mongo_service = new MongoService();
$ret = $mongo_service->getUser();
var_dump($ret);
exit;
}
public function getManyAction()
{
$mongo_service = new MongoService();
$ret = $mongo_service->getManyUser();
var_dump($ret);
exit;
}
}
<?php
use App\Base\Base;
use App\Services\demo\MysqlService;
class MysqlController extends Base
{
public function addAction(){
$mysql_service = new MysqlService();
$ret = $mysql_service->addUser();
var_dump($ret);
exit;
}
public function addManyAction(){
$mysql_service = new MysqlService();
$ret = $mysql_service->addManyUser();
var_dump($ret);
exit;
}
public function deleteAction(){
$mysql_service = new MysqlService();
$ret = $mysql_service->deleteUser();
var_dump($ret);
exit;
}
public function updateAction(){
$mysql_service = new MysqlService();
$ret = $mysql_service->updateUser();
var_dump($ret);
exit;
}
public function getAction()
{
$mysql_service = new MysqlService();
$ret = $mysql_service->getUser();
var_dump($ret);
exit;
}
public function getManyAction(){
$mysql_service = new MysqlService();
$ret = $mysql_service->getManyUser();
var_dump($ret);
exit;
}
public function countAction(){
$mysql_service = new MysqlService();
$ret = $mysql_service->countUser();
var_dump($ret);
exit;
}
public function maxAction(){
$mysql_service = new MysqlService();
$ret = $mysql_service->maxUser();
var_dump($ret);
exit;
}
public function minAction(){
$mysql_service = new MysqlService();
$ret = $mysql_service->minUser();
var_dump($ret);
exit;
}
public function avgAction(){
$mysql_service = new MysqlService();
$ret = $mysql_service->avgUser();
var_dump($ret);
exit;
}
public function sumAction(){
$mysql_service = new MysqlService();
$ret = $mysql_service->sumUser();
var_dump($ret);
exit;
}
}
<?php
use App\Base\Base;
use Api\PhpUtils\Http\Request;
class RequestController extends Base
{
public function GetAction()
{
$url = 'http://10.103.17.132:8007/adserver/goodsAds';
$options = [
'query' => [
'docIdList' => '0SQ0d3dH',
'appId' => 'pro',
'platform' => 0
],
'timeout' => 0.5 //自定义超时秒数,覆盖默认值
];
$request = new Request();
$ret = $request->get($url, $options);
var_dump($ret);
exit;
}
public function PostAction(){
$url = 'http://sso.dengwei4378.com/api/master/getInfoByMasterName';
$options = [
'form_params' => [
"masterName" => 'dengwei4378',
"system" => 'rbac'
],
'timeout' => 1 //自定义超时秒数,覆盖默认值
];
$request = new Request();
$post_ret = $request->post($url, $options);
var_dump($post_ret);
exit;
}
/**
* 并发GET
*/
public function ConGetAction(){
$params = [
0 => [
'url' => 'http://sso.dengwei4378.com',
'timeout' => 3 //自定义超时秒数,覆盖默认值
],
1 => [
'url' => 'https://api.github.com/',
'timeout' => 3 //自定义超时秒数,覆盖默认值
],
];
$request = new Request();
$ret = $request->concurrencyGet($params);
var_dump($ret);
exit;
}
public function ConPostAction(){
$params = [
0 => [
'url' => 'http://lock-screen-push.int.yidian-inc.com/lock-screen/list',
'headers' => [
'Content-type' => 'application/json',
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36'
],
'json' => [ //json格式
"bizid" => "YDZX",
"uid" => "765073697",
"platform" => "1",
"appid" => "hipu"
],
'timeout' => 0.1 //自定义超时秒数,覆盖默认值
],
1 => [
'url' => 'http://sso.dengwei4378.com/api/master/getInfoByMasterName',
'form_params' => [ //表单格式
"masterName" => 'dengwei4378',
"system" => 'rbac'
],
'timeout' => 0.2 //自定义超时秒数,覆盖默认值
],
];
$request = new Request();
$ret = $request->concurrencyPost($params);
var_dump($ret);
exit;
}
}
<?php
use App\Base\Base;
use Helpers\Aes;
use Api\PhpUtils\Http\Request;
use Api\PhpServices\Session\SessionManager;
use App\Exception\BaseException;
class SessionController extends Base
{
public function StartAction()
{
// $key = 'asdfasdfasdfasdf';
// $iv = 'fdsafdsafdsafdsa';
// $salt = "12341/5";
// var_dump(base64_encode($salt));
// var_dump(strtolower(str_replace(array('+','/','='), array(''), base64_encode($salt))));
// var_dump($data = openssl_encrypt($salt, "AES-128-CBC", $key, 0, $iv));
// var_dump(openssl_decrypt($data, "AES-128-CBC", $key, 0, $iv));
// exit;
// $result = (new Request())->get('http://10.126.171.30:18080/topom', [], 1);
// // $proxy = $result['stats']['proxy'];
// $server = $result['stats']['group']['models'];
// $arr = [];
// foreach ($server as $item) {
// $arr[] = $item['servers'][1]['server'];
// }
// print_r($arr);
// exit;
// print_r(\Yaconf::get('interface.test.service'));exit;
// echo $s = '{'.str_replace(array('+','/','='), array('-','_',''), base64_encode('12345')).'}';
// exit;
// $s = json_decode(json_encode(['a' =>'{MTIzNDU}e3eec597a5a3f9420b445c89d38a6fbc7c']),true);
// print_r($s);exit;
// phpinfo();exit;
// $key = 'interface.test.service.session.get';
// echo \Yaconf::get($key);
// exit;
$ret = SessionManager::start();
// print_r($_SERVER);
// print_r($_COOKIE);
var_dump($ret);
print_r($_SESSION);
// $ret1 = SessionManager::destroy();
// // print_r($_SERVER);
// // print_r($_COOKIE);
// var_dump($ret1);
// print_r($_SESSION);
// var_dump($ret);
}
public function CreateAction()
{
$ret = SessionManager::set('metro', '12345', true, ['a' => 'aaa', 'b' => 'bbb', 'c' => 'ccc', 'd' => 'ddd'], 1);
var_dump($ret);
print_r($_SESSION);
exit;
}
public function DestroyAction()
{
$ret = SessionManager::destroy();
// print_r($_SERVER);
// print_r($_COOKIE);
var_dump($ret);
print_r($_SESSION);
}
public function GetAction()
{
print_r($request = $this->getRequest()->getRequest());
$sessionid = $request['sid'] ?? 'aedcc37ea232aade90037716ddab1debe6';
$url = $this->getBaseUri() . '/get-session';
$query = ['sessionid' => $sessionid];
// $query = ['sessionid' => 'jssionidtest'];
$result = (new Request())->get($url, $query, 3000);
print_r($result);
exit;
if (isset($result['code']) && $result['code'] == 0 ) {
return true;
}
return false;
}
public function SetAction()
{
$url = $this->getBaseUri() . '/set-session';
$sessionData = ['id' => 123, 'name' => 'test'];
$params = ['sessionid' => 'jssionidtest11', 'data' => ($sessionData), 'expire' => 600, 'key' => 'c071f6e5923a648a5ef88f32b6f738e1'];
$result = (new Request())->post($url, $params, 1000, 'json');
print_r($result);
}
public function DelAction()
{
$url = $this->getBaseUri() . '/delete-session';
$query = ['sessionid' => ['jssionidtest1', 'jssionidtest'], 'key' =>'c071f6e5923a648a5ef88f32b6f738e1'];
$result = (new Request())->get($url, $query, 1000);
print_r($result);
}
public function MgetAction()
{
$url = $this->getBaseUri() . '/get-many-session';
$query = ['sessionid' =>['YPZQISU1Tjxg3wJLFWJmVA', 'E4vo3R5EfaPS-pnyDzia3Q']];
$result = (new Request())->get($url, $query, 2000);
print_r($result);
exit;
$url = $this->getBaseUri() . '/get-many-session';
$query = ['sessionid' =>['jssionidtest2', 'jssionidtest1']];
$result = (new Request())->get($url, $query, 2000);
print_r($result);
exit;
// $validSessionIds[] = 'a';
// $validSessionIds[] = 'b';
// $validSessionIds[] = 'c';
// echo $validSessionIds[rand(0, count($validSessionIds) - 1)];
// exit;
// // todo 请求接口读redis
// echo $url = $this->getBaseUri() . '/get-session1';
// $query = ['sessionid' => 'jssionidtest'];
// $result = (new Request())->get($url, $query, 1000);
// if (isset($result['code']) && $result['code'] == 0 && isset($result['result'])) {
// $data = $result['result'];
// print_r($data);
// }else {
// print_r($result);
// }
// exit;
// $r = \Api\PhpUtils\Common\IP::find('114.114.114.114');
// print_r($r);
// exit;
// $_SESSION['abc'] = 'ttt';
// echo $_SESSION['abc'];
// echo $_SESSION['abc'];
// echo $_SESSION['abc'];
// echo $_SESSION['abc'];
// exit;
// $abc = '123'. "\x7F" . 456;
// var_dump($abc);exit;//string(7) "123456" 不可见字任作为分隔符
// $a = base64_encode('6543211111dasfsdfasdf1111asdfasdfs1111');
// var_dump($a);
// var_dump(sha1($a));
// var_dump(substr(sha1($a), -2));
// $a = $a . substr(sha1($a), -2);
// var_dump($a);
// var_dump(substr($a, 0, -2));
// $a = substr($a, 0, -2);
// var_dump($a);
// var_dump(sha1($a));
// var_dump(substr(sha1($a), -2));
// exit;
// var_dump(strlen($a));
// var_dump($a);exit;
// var_dump($this->response);
// var_dump(Yaf\Dispatcher::getInstance()->getResponse());
// exit;
// $data = ['appid'=> 'appid', 'verison'=>'023200', 'reqid'=>'11adddddddfasdfasdfasdfasdfdsafwerqwersfasfasdvasdfsdfffs1', 'platform'=>'1', 'ts' => ceil(microtime(true) * 1000)];
// echo $sign = Aes::createSign($data);
// exit;
// $data = ['appid'=> 'appid', 'verison'=>'023200', 'reqid'=>'111', 'platform'=>'1'];
// $data['sign'] = 'l4lBCE3B_v-ODFeuoxFksl0IUY9ehBnjN_FtU3ESdrn_bMPDsEIxA8IUw0pDJ_kX06P6OOw23in46acBucgceSBE2Vx3Ew52w3FfmRn8IhE';
// $sign = Aes::checkSign($data);
// var_dump($sign);
// exit;
// $obj = new App\Models\User();
// print_r($obj->getUserData());//Array ( [name] => zhangsan [age] => 18 )
// exit;
// $http = $this->getRequest()->getRequest();
// var_dump($http);
// var_dump(file_get_contents("php://input"));
// var_dump($this->requestAll());yaf
// exit;
$res = [
"userid" => 'user',
"code" => 0
];
// print_r($this->failed(-1,'reason'));
$this->success($res);
}
/**
* get uri
* @return string
*/
public function getBaseUri()
{
$env = \Yaf\Application::app()->environ() ?? "dev1";
if ($env == 'product') {
$this->baseUri = 'http://a4.go2yd.com/Website/session';
}elseif ($env == 'dev') {
$this->baseUri = 'http://127.0.0.1/Website/session';
}else {
$this->baseUri = 'http://a4-1.go2yd.com/Website/session';
}
return $this->baseUri;
}
}
\ No newline at end of file
<?php
use App\Base\Base;
class TestController extends Base
{
public function indexAction()
{
$this->success();
}
}
<?php
use App\Base\Base;
use Helpers\Aes;
use Api\PhpUtils\Http\Request;
use Api\PhpUtils\Redis\RedisUtil;
use App\Models\demo\mongo\Test;
use Api\PhpUtils\Common\Rsa;
use Api\PhpServices\Session\SessionManager;
use Helpers\DebugLog;
use Api\PhpUtils\Kafka\KafkaUtil;
use Api\PhpUtils\Cache\ApcuUtil;
use Api\PhpUtils\Cache\CacheUtil;
use Api\PhpServices\Doc\DocDynamic;
use App\Models\demo\mysql\TestMysql;
class TttController extends Base
{
/**
* @var Api\PhpUtils\Cache\CacheUtil;
*/
protected $cache;
public function mysqlAction()
{
// $ret = TestMysql::getRecord(['life_account_id' => 8281925009833985]);
// $ret = TestMysql::getRecords(['life_account_id' => 8281925009833985]);
// $ret = TestMysql::duplicate([['id' => 4,'name' => 'test3'], ['id' => 5,'name' => 'test4']], ['name' => Api\PhpUtils\Mysql\Medoo::raw('VALUES(name)')]);
// $ret = TestMysql::selectForUpdate('*', ['id' => 5], ['max_execution_time' => 1]);
$ret = TestMysql::count('*', ['id[>]' =>2]);
var_dump($ret);
}
public function kafkaAction()
{
$topicName = 'topicA';
$setConfDrMsgCb = function ($kafka, \RdKafka\Message $message) {
echo '打印消息:' . "\n";
var_export($message);
echo "\n";
if($message->err){
//@todo 生产失败的逻辑处理
} else{
//@todo 生产成功的逻辑处理
}
};
$setErrorCbCallback = function ($kafka, $err, $reason) {
echo sprintf("setErrorCb (error_ori:%s)(error: %s) (reason: %s)", $err, rd_kafka_err2str($err), $reason);
};
// $kafka = KafkaUtil::getInstance('test', ['context' => ['contextArr']]);
// $ret = $kafka->produce('eee');
$brokers = '127.0.0.1:9092';
$kafka = KafkaUtil::getInstance();
$ret = $kafka->setBrokers($brokers)->setTopicName('topicA')->produce('ccc');
var_dump($ret);
var_dump($kafka);
exit;
//设置brokers-支持数组或者字符串
$kafka->setBrokers($brokers)
//设置topic
->setTopicName($topicName)
//setConfDrMsgCb--设置生产消息失败与成功的回调,默认初始化时会调用该事件,如果自定义后就会覆盖底层的事件
->setConfDrMsgCb($setConfDrMsgCb)
//setConfErrorCb--设置错误回调,如若不设置默认会走该逻辑进行:\RdKafkaSdk\Core\Conf::defaultInit
->setConfErrorCb($setErrorCbCallback)
//支持连贯用法生产多条数据并且是不同的topic
->run('message111', $topicName);
/**
object(Api\PhpUtils\Kafka\KafkaUtil)#17 (12) {
["serverName":"Api\PhpUtils\Kafka\KafkaUtil":private]=>
string(0) ""
["producer":"Api\PhpUtils\Kafka\KafkaUtil":private]=>
object(RdKafka\Producer)#22 (2) {
["error_cb":"RdKafka":private]=>
NULL
["dr_cb":"RdKafka":private]=>
NULL
}
["conf":"Api\PhpUtils\Kafka\KafkaUtil":private]=>
object(RdKafka\Conf)#18 (0) {
}
["confSet":"Api\PhpUtils\Kafka\KafkaUtil":private]=>
array(8) {
["socket.timeout.ms"]=>
int(50)
["socket.blocking.max.ms"]=>
int(50)
["topic.metadata.refresh.sparse"]=>
bool(true)
["topic.metadata.refresh.interval.ms"]=>
int(600)
["socket.nagle.disable"]=>
bool(true)
["message.timeout.ms"]=>
int(50)
["log_level"]=>
int(4)
["internal.termination.signal"]=>
int(23)
}
["confFunction":"Api\PhpUtils\Kafka\KafkaUtil":private]=>
array(2) {
["setDrMsgCb"]=>
object(Closure)#20 (3) {
["static"]=>
array(1) {
["context"]=>
array(0) {
}
}
["this"]=>
*RECURSION*
["parameter"]=>
array(2) {
["$kafka"]=>
string(10) "<required>"
["$message"]=>
string(10) "<required>"
}
}
["setErrorCb"]=>
object(Closure)#21 (2) {
["this"]=>
*RECURSION*
["parameter"]=>
array(3) {
["$kafka"]=>
string(10) "<required>"
["$err"]=>
string(10) "<required>"
["$reason"]=>
string(10) "<required>"
}
}
}
["topicConf":"Api\PhpUtils\Kafka\KafkaUtil":private]=>
object(RdKafka\TopicConf)#19 (0) {
}
["topicConfSet":"Api\PhpUtils\Kafka\KafkaUtil":private]=>
array(1) {
["request.required.acks"]=>
int(1)
}
["topicConfFunction":"Api\PhpUtils\Kafka\KafkaUtil":private]=>
array(0) {
}
["brokers":"Api\PhpUtils\Kafka\KafkaUtil":private]=>
string(14) "127.0.0.1:9092"
["topicName":"Api\PhpUtils\Kafka\KafkaUtil":private]=>
string(6) "topicA"
["context":"Api\PhpUtils\Kafka\KafkaUtil":private]=>
array(0) {
}
["config":"Api\PhpUtils\Kafka\KafkaUtil":private]=>
array(3) {
["viewlog"]=>
array(2) {
["topic"]=>
string(16) "dw_metro_pb_view"
["broker_list"]=>
array(15) {
[0]=>
string(32) "c1-e14-120-24-23.yidian.com:9092"
[1]=>
string(32) "c1-e14-120-24-24.yidian.com:9092"
[2]=>
string(32) "c1-e14-120-24-25.yidian.com:9092"
[3]=>
string(32) "c1-e14-120-24-26.yidian.com:9092"
[4]=>
string(32) "c1-e14-120-24-27.yidian.com:9092"
[5]=>
string(31) "c1-e15-120-25-6.yidian.com:9092"
[6]=>
string(31) "c1-e15-120-25-7.yidian.com:9092"
[7]=>
string(31) "c1-e15-120-25-8.yidian.com:9092"
[8]=>
string(31) "c1-e15-120-25-9.yidian.com:9092"
[9]=>
string(32) "c1-e16-120-25-10.yidian.com:9092"
[10]=>
string(32) "c1-e16-120-25-17.yidian.com:9092"
[11]=>
string(32) "c1-e16-120-25-18.yidian.com:9092"
[12]=>
string(32) "c1-e17-120-25-19.yidian.com:9092"
[13]=>
string(32) "c1-e17-120-25-20.yidian.com:9092"
[14]=>
string(32) "c1-e17-120-25-21.yidian.com:9092"
}
}
["subscribe"]=>
array(2) {
["topic"]=>
string(15) "dw_metro_pb_api"
["broker_list"]=>
array(15) {
[0]=>
string(32) "c1-e14-120-24-23.yidian.com:9092"
[1]=>
string(32) "c1-e14-120-24-24.yidian.com:9092"
[2]=>
string(32) "c1-e14-120-24-25.yidian.com:9092"
[3]=>
string(32) "c1-e14-120-24-26.yidian.com:9092"
[4]=>
string(32) "c1-e14-120-24-27.yidian.com:9092"
[5]=>
string(31) "c1-e15-120-25-6.yidian.com:9092"
[6]=>
string(31) "c1-e15-120-25-7.yidian.com:9092"
[7]=>
string(31) "c1-e15-120-25-8.yidian.com:9092"
[8]=>
string(31) "c1-e15-120-25-9.yidian.com:9092"
[9]=>
string(32) "c1-e16-120-25-10.yidian.com:9092"
[10]=>
string(32) "c1-e16-120-25-17.yidian.com:9092"
[11]=>
string(32) "c1-e16-120-25-18.yidian.com:9092"
[12]=>
string(32) "c1-e17-120-25-19.yidian.com:9092"
[13]=>
string(32) "c1-e17-120-25-20.yidian.com:9092"
[14]=>
string(32) "c1-e17-120-25-21.yidian.com:9092"
}
}
["test"]=>
array(2) {
["topic"]=>
string(6) "topicA"
["broker_list"]=>
array(1) {
[0]=>
string(14) "localhost:9092"
}
}
}
}
*/
}
public function docAction() {
$obj = new DocDynamic(true);
$docs = array(
'06No4hkp'=>array('like'=>1,'down'=>2),
'06No4hk1'=>array('comment_count'=>3,'up'=>4,'comment_like'=>'7'));
// $set = $obj->incrCommentCount('06No4hkp');
$set = $obj->setThumbsdown('06No4hkp', 1);
var_dump($set);
// $ret = $obj->get('08yidV11');
$ret = $obj->get('06No4hkp');
// $ret = $obj->get('news_b428c553fcb900ba3624385a818f1368');
// $ret = $obj->gets(['news_b428c553fcb900ba3624385a818f1368']);
// var_dump($obj);
var_dump($ret);
exit;
}
public function apcuAction() {
// $prefix_key = ApcuUtil::add_prefix('prefix', 'key1');
// var_dump($prefix_key);
// $ret = ApcuUtil::apcu_store_one('prefix', 'key1', 'value1', 10);
// $set = ApcuUtil::apcu_add_one('prefix', 'key1', 'value1', 3);
// $set = ApcuUtil::apcu_add_multi('prefix', ['key1' => 'value2', 'key2' => 'value3'], null, 10);
$set = ApcuUtil::apcu_store_multi('prefix', ['key1' => 'value1', 'key2' => 'value2'], null, 10);
// $del = ApcuUtil::apcu_delete('prefix', 'key2');
$get = ApcuUtil::apcu_fetch('prefix', 'key3', $success);
// $get = ApcuUtil::apcu_fetch('prefix', ['key1', 'key2'], $success);
var_dump($set);
// var_dump($del);
var_dump($get);
// var_dump($success);
exit;
}
public function redisAction() {
// $arr = ['serverRegion'=> 'sh', 'serializer' => 'none', 'master'=> false];
// var_dump('abc'.serialize($arr));
// $str = 'abc'. json_encode($arr);
// var_dump($str);
// exit;
$redis = RedisUtil::getInstance('api', ['serverRegion'=> 'sh', 'serializer' => 'none', 'master'=> true]);
$redis = RedisUtil::getInstance('api', ['serverRegion'=> 'sh', 'serializer' => 'none', 'master'=> true]);
// var_dump($redis);
$get = $redis->hget('07IqF', 'Vcc');
var_dump($get);
exit;
// echo 123456;exit;
// codis
$redis = RedisUtil::getInstance('redis', ['serverRegion'=> 'wj', 'serializer' => 'none', 'master'=> true]);
var_dump($redis);exit;
$set = $redis->setex('ebbddse',20, 'value123');
// $redis = RedisUtil::getInstance('redis', ['serverRegion'=> 'wj', 'serializer' => 'igbinary', 'master'=> false]);
// $set = $redis->setex('ebbddse',200, ['value111', 'value222']);
// $set = $redis->del('ebbddse');
var_dump($set);
$get = $redis->get('ebbddse');
// $get = $redis->get('myAppName:ebbddse');
var_dump($get);
// Sentinel
// $redis = RedisUtil::getInstance('sentinel', 'region2', true);
// $ret = $redis->set('bbdadfsdd', 'sentinel');
// $ret = $redis->get('bbdadfsdd');
// $ret = $redis->get('myAppName:ebbddse');
// var_dump($ret);
// Redis
// $redis = RedisUtil::getInstance('redis');
// $ret = $redis->setex('sdddadfeasdfsdaf', 5, "a".'["redis1", "redis2"]');
// $ret = $redis->set('sdddadfeasdfsdaf', 'redis');
// $ret = $redis->get('sdddadfeasdfsdaf');
// $ret = $redis->del('sdddadfeasdfsdaf');
// $ret = $redis->get('myAppName:sdddadfeasdfsdaf');
// var_dump($ret);
// print_r($redis);
// var_dump($redis);
exit;
}
public function cacheAction() {
$this->cache = CacheUtil::getInstance('redis', ['serializer' => 'none']);
$this->cache->get('07IqF', 'Vcc');
$cache = CacheUtil::getInstance('redis', ['serializer' => 'none']);
// var_dump($cache);exit;
// $set = $cache->setex('ebbddse',200, 'value123');
// $set = $cache->setex('ebbddse',20, ['value111', 'value222']);
// $set = $cache->del('ebbddse');
$set = $cache->sets(['k1' => 'v1', 'k2' => 'v2'], 100, 'p');
var_dump($set);
$get = $cache->get('ebbddse');
$get = $cache->gets(['k1', 'k2', 'keykkk'], 'p');
// $get = $cache->gets(['ebbddse','key1', 'keykkk']);
// $get = $cache->get('myAppName:ebbddse');
var_dump($get);
exit;
}
public function debuglogAction() {
$sessionData = ['id' => 123, 'name' => 'test'];
print_r($sessionData);
DebugLog::time('1.php, start page');
sleep(1);
DebugLog::time('2.php, start page');
sleep(1);
DebugLog::time('3.php, start page');
DebugLog::log('log1', 'log1_info');
exit;
}
public function IndexAction() {
$ret = SessionManager::start(false,'yidian');
// print_r($_SERVER);
// print_r($_COOKIE);
var_dump($ret);
print_r($_SESSION);
$url = $this->getBaseUri() . '/get-many-session';
$query = ['sessionid' =>['YPZQISU1Tjxg3wJLFWJmVA', 'E4vo3R5EfaPS-pnyDzia3Q']];
$result = (new Request())->get($url, ['query' => $query, 'timeout' => 1]);
print_r($result);
exit;
// $validSessionIds[] = 'a';
// $validSessionIds[] = 'b';
// $validSessionIds[] = 'c';
// echo $validSessionIds[rand(0, count($validSessionIds) - 1)];
// exit;
// todo 请求接口写redis
$url = $this->getBaseUri() . '/set-session';
$sessionData = ['id' => 123, 'name' => 'test'];
$params = ['sessionid' => 'jssionidtest', 'data' => ($sessionData), 'expire' => 600, 'key' => 'c071f6e5923a648a5ef88f32b6f738e1'];
$result = (new Request())->post($url, ['form_params' => $params, 'timeout' => 1]);
print_r($result);
// exit;
$url = $this->getBaseUri() . '/get-many-session';
$query = ['sessionid' =>['jssionidtest2', 'jssionidtest1']];
$result = (new Request())->get($url, ['query' => $query, 'timeout' => 1]);
print_r($result);
exit;
$url = $this->getBaseUri() . '/delete-session';
$query = ['sessionid' => ['jssionidtest1', 'jssionidtest'], 'key' =>'c071f6e5923a648a5ef88f32b6f738e1'];
$result = (new Request())->get($url, ['query' => $query, 'timeout' => 1]);
print_r($result);
$url = $this->getBaseUri() . '/get-session';
$query = ['sessionid' => 'jssionidtest'];
$result = (new Request())->get($url, ['query' => $query, 'timeout' => 1]);
print_r($result);
exit;
if (isset($result['success']['code']) && $result['success']['code'] == 0 ) {
return true;
}
return false;
// // todo 请求接口读redis
// echo $url = $this->getBaseUri() . '/get-session1';
// $query = ['sessionid' => 'jssionidtest'];
// $result = (new Request())->get($url, ['query' => $query, 'timeout' => 1]);
// if (isset($result['success']['code']) && $result['success']['code'] == 0 && isset($result['success']['result'])) {
// $data = $result['success']['result'];
// print_r($data);
// }else {
// print_r($result);
// }
// exit;
// $r = \Api\PhpUtils\Common\IP::find('114.114.114.114');
// print_r($r);
// exit;
// $_SESSION['abc'] = 'ttt';
// echo $_SESSION['abc'];
// echo $_SESSION['abc'];
// echo $_SESSION['abc'];
// echo $_SESSION['abc'];
// exit;
// $abc = '123'. "\x7F" . 456;
// var_dump($abc);exit;//string(7) "123456" 不可见字任作为分隔符
// $a = base64_encode('6543211111dasfsdfasdf1111asdfasdfs1111');
// var_dump($a);
// var_dump(sha1($a));
// var_dump(substr(sha1($a), -2));
// $a = $a . substr(sha1($a), -2);
// var_dump($a);
// var_dump(substr($a, 0, -2));
// $a = substr($a, 0, -2);
// var_dump($a);
// var_dump(sha1($a));
// var_dump(substr(sha1($a), -2));
// exit;
// var_dump(strlen($a));
// var_dump($a);exit;
// var_dump($this->response);
// var_dump(Yaf\Dispatcher::getInstance()->getResponse());
// exit;
// $data = ['appid'=> 'appid', 'verison'=>'023200', 'reqid'=>'11adddddddfasdfasdfasdfasdfdsafwerqwersfasfasdvasdfsdfffs1', 'platform'=>'1', 'ts' => ceil(microtime(true) * 1000)];
// echo $sign = Aes::createSign($data);
// exit;
// $data = ['appid'=> 'appid', 'verison'=>'023200', 'reqid'=>'111', 'platform'=>'1'];
// $data['sign'] = 'l4lBCE3B_v-ODFeuoxFksl0IUY9ehBnjN_FtU3ESdrn_bMPDsEIxA8IUw0pDJ_kX06P6OOw23in46acBucgceSBE2Vx3Ew52w3FfmRn8IhE';
// $sign = Aes::checkSign($data);
// var_dump($sign);
// exit;
// $obj = new App\Models\User();
// print_r($obj->getUserData());//Array ( [name] => zhangsan [age] => 18 )
// exit;
// $http = $this->getRequest()->getRequest();
// var_dump($http);
// var_dump(file_get_contents("php://input"));
// var_dump($this->requestAll());yaf
// exit;
$res = [
"userid" => 'user',
"code" => 0
];
// print_r($this->failed(-1,'reason'));
$this->success($res);
}
public function MongoAction()
{
$ret = [];
$obj = Test::getInstance();
$cursor = $obj->findOne(["_id" => 8], ['projection' => ['name' => 1, '_id' => 0]]);
print_r($cursor);
$ret = $obj->insertOne(["_id" => 8, "mobile" => "17701340008"]);
$ret = $obj->insertMany([["_id" => 9, "mobile" => "17701340008"], ["_id" => 8, "mobile" => "17701340009"]]);
$ret = $obj->insertOne(["_id" => 8, "mobile" => "17701340008"]);
$ret = $obj->updateOne(["_id" => 8], [ '$set' => ["mobile" => "177013400081"]]);
$ret = $obj->updateMany(["_id" => 8], [ '$set' => ["mobile" => "177013400081"]]);
$ret = $obj->findOneAndUpdate(["_id" => 8], [ '$set' => ["mobile" => "177013400081"]]);
$ret = $obj->findOneAndDelete(["_id" => 9]);
$ret = $obj->deleteMany(["_id" => 9]);
echo $ret->getDeletedCount();
echo $ret->getInsertedCount();
echo $ret->getInsertedId();
print_r($ret->getInsertedIds());
echo $ret->getMatchedCount();
echo $ret->getModifiedCount();
echo $ret->getUpsertedCount();
echo $ret->getUpsertedId();
$cursor = $obj->find();
foreach ($cursor as $k => $document) {
// var_dump($document);exit;
$ret[$k] = $document;
}
$ret = $obj->countDocuments();
print_r($ret);
exit;
}
public function HttpAction()
{
$http = $this->getRequest()->getRequest();
var_dump($http);
var_dump(file_get_contents("php://input"));
var_dump($this->requestAll());
exit;
}
public function IpAction()
{
$r = \Api\PhpUtils\Common\IP::find('123.100.1.111');
print_r($r);
// exit;
$r = \Api\PhpUtils\Common\IP::find('121.103.40.115');
print_r($r);
$r = \Api\PhpUtils\Common\IP::find('122.103.40.115');
print_r($r);
$r = \Api\PhpUtils\Common\IP::find('123.103.8.115');
print_r($r);
exit;
}
public function RsaAction()
{
$r = \Api\PhpUtils\Common\IP::find('114.114.114.114');
print_r($r);
exit;
}
public function AesAction()
{
$data['sign'] = "Fcz71y9zBf4cYEHcg52ZzvfY3qIrv_6ydx08WTOQfg0xj-HepuW9v277GV72zFi-uJXg5YVgVbdxbi0QEUpL5g";
$sign = Aes::checkSign($data);
var_dump($sign);
exit;
$data = ['appid'=> 'appid', 'verison'=>'023200', 'reqid'=>'11adddddddfasdfasdfasdfasdfdsafwerqwersfasfasdvasdfsdfffs1', 'platform'=>'1', 'ts' => ceil(microtime(true) * 1000)];
echo $sign = Aes::createSign($data);
exit;
$data = ['appid'=> 'appid', 'verison'=>'023200', 'reqid'=>'111', 'platform'=>'1'];
$data['sign'] = 'l4lBCE3B_v-ODFeuoxFksl0IUY9ehBnjN_FtU3ESdrn_bMPDsEIxA8IUw0pDJ_kX06P6OOw23in46acBucgceSBE2Vx3Ew52w3FfmRn8IhE';
$sign = Aes::checkSign($data);
var_dump($sign);
exit;
}
/**
* get url
* @return string
*/
public function getBaseUri()
{
$env = \Yaf\Application::app()->environ() ?? "dev";
if ($env == 'product') {
$this->baseUri = 'http://a4.go2yd.com/Website/session';
}elseif ($env == 'dev') {
$this->baseUri = 'http://127.0.0.1/Website/session';
}else {
$this->baseUri = 'http://a4-1.go2yd.com/Website/session';
}
return $this->baseUri;
}
}
\ No newline at end of file
## modules
#### 第一层文件夹 首字母要大写 ,请参考Test/controllers目录,
#### 已有的Test目录,请在开发时删除
\ No newline at end of file
<?php
namespace App\Plugins;
use App\Exception\ExceptionErrorCatch;
use Helpers\DebugLog;
class Hook extends \Yaf\Plugin_Abstract {
public function routerStartup(\Yaf\Request_Abstract $request, \Yaf\Response_Abstract $response) {
// 重定义异常处理
ExceptionErrorCatch::register();
}
public function routerShutdown(\Yaf\Request_Abstract $request, \Yaf\Response_Abstract $response) {
/*---Debug Begin---*/
if((defined('_IS_DEBUG') && _IS_DEBUG) && (isset($_REQUEST['__debug']) && strpos($_REQUEST['__debug'], _DEBUG_PASS) !== false))
{
// $_REQUEST['__debug'] = _DEBUG_PASS + 1 (2 数字表示级别 )
$debug_level = intval(substr($_REQUEST['__debug'], -1));
if ($debug_level > 0) {
define('DEBUG_LEVEL', $debug_level );
} else {
define('DEBUG_LEVEL', 1);
}
//Debug模式将错误打开
ini_set('display_errors', true);
//设置错误级别
error_reporting(_ERROR_LEVEL);
//开启ob函数
ob_start();
//Debug开关打开
DebugLog::init();
//注册shutdown函数用来Debug显示
register_shutdown_function(array('Helpers\DebugLog', 'show'));
} else {
define('DEBUG_LEVEL', 0);
}
// 调试探针,初始化完成,页面开始执行
DebugLog::time('init.php, start page');
}
public function dispatchLoopStartup(\Yaf\Request_Abstract $request, \Yaf\Response_Abstract $response) {
}
public function preDispatch(\Yaf\Request_Abstract $request, \Yaf\Response_Abstract $response) {
//处理$_POST, $_REQUEST请求,兼容application/json形式
if(!$_POST && $request->isPost()
&& $request->getServer('CONTENT_TYPE') == 'application/json') {
$jsonPost = file_get_contents("php://input");
if($jsonPost) {
$_POST = json_decode($jsonPost, true);
$ini = ini_get('request_order');
if($ini) {
$arrIni = str_split($ini, 1);
foreach($arrIni as $type) {
if(strtoupper($type) === 'G') {
$_REQUEST = array_merge($_REQUEST, $_GET);
}elseif(strtoupper($type) === 'P') {
$_REQUEST = array_merge($_REQUEST, $_POST);
}
}
}
}
}
}
public function postDispatch(\Yaf\Request_Abstract $request, \Yaf\Response_Abstract $response) {
}
public function dispatchLoopShutdown(\Yaf\Request_Abstract $request, \Yaf\Response_Abstract $response) {
}
}
<?php
namespace App\Services\demo;
use App\Models\demo\mongo\User;
class MongoService
{
public function addUser()
{
$user = User::getInstance();
$data = [
'_id' => 4,
'name' => 'dw04',
'mobile' => '17701340004'
];
return $user->add($data);
}
public function addManyUser()
{
$user = User::getInstance();
$data = [
[
'_id' => 5,
'name' => 'dw05',
'mobile' => '17701340005'
],
[
'_id' => 6,
'name' => 'dw06',
'mobile' => '17701340006'
]
];
return $user->addMany($data);
}
public function deleteUser()
{
$user = User::getInstance();
$params = [
'name' => 'dw01'
];
return $user->delete($params);
}
public function updateUser()
{
$user = User::getInstance();
$params = [
'name' => 'dw02'
];
$data = [
'mobile' => '17701340002'
];
return $user->update($params, $data);
}
public function getUser()
{
$user = User::getInstance();
$params = [
'name' => 'dw02'
];
return $user->get($params);
}
public function getManyUser()
{
$user = User::getInstance();
$params = [
'name' => 'dw02'
];
return $user->getMany($params);
}
}
<?php
namespace App\Services\demo;
use App\Models\demo\mysql\User;
class MysqlService
{
public function addUser()
{
$user = User::getWriteInstance();
$data = [
'name' => 'dw07',
'mobile' => '17701340007'
];
return $user->add($data);
}
public function addManyUser()
{
$user = User::getWriteInstance();
$data = [
[
'name' => 'dw08',
'mobile' => '17701340008'
],
[
'name' => 'dw09',
'mobile' => '17701340009'
]
];
return $user->addMany($data);
}
public function deleteUser()
{
$user = User::getWriteInstance();
$params = [
'name' => 'dw08'
];
return $user->delete($params);
}
public function updateUser()
{
$user = User::getWriteInstance();
$params = [
'name' => 'dw02'
];
$data = [
'mobile' => '15030690002'
];
return $user->update($params, $data);
}
public function getUser()
{
$user = User::getInstance();
$params = [
'name' => 'dw02'
];
$column = [
'name',
'mobile'
];
return $user->get($params, $column);
}
public function getManyUser()
{
$user = User::getInstance();
$params = [
'id[>]' => 3
];
$column = [
'name',
'mobile'
];
return $user->getMany($params, $column);
}
public function countUser()
{
$user = User::getInstance();
$params = [
'master_name' => 'dw04'
];
$column = 'id';
return $user->count($params, $column);
}
public function maxUser()
{
$user = User::getInstance();
$params = [
'id[>]' => 1
];
$column = 'id';
return $user->max($params, $column);
}
public function minUser()
{
$user = User::getInstance();
$params = [
'id[>]' => 1
];
$column = 'id';
return $user->min($params, $column);
}
public function avgUser()
{
$user = User::getInstance();
$params = [
'id[>]' => 1
];
$column = 'id';
return $user->avg($params, $column);
}
public function sumUser()
{
$user = User::getInstance();
$params = [
'id[>]' => 1
];
$column = 'id';
return $user->sum($params, $column);
}
}
<?php
namespace App\Services\order;
class OrderService
{
public static function get_idgen_id($number, $count=1){
$res = Idgen::get(appConfig('idgen.partner'),appConfig('idgen.key'), [], [[
"type" => "merchant_shop_id",
'number'=>$number,
"count"=> $count]]);
$id = $res['id_datetime']['merchant_shop_id'] ?? [];
return $id;
}
/**
* @param $orderId
* @param $userId
* 调用内部服务获取用户订单、子单、分润信息
*/
public static function getOrderData($orderId, $userId) {
return self::getDemoData($orderId, $userId);
}
public static function getDemoData($orderId, $userId) {
$order = [
'order_id'=>$orderId,
'user_id'=>$userId,
'life_account_id'=>2312, //'生活号id',
'shop_id'=>2312, //'店铺shop_id',
'order_type'=>1, //'1虚拟商品,2实体商品',
'payment'=>1, //'1虚拟商品,2实体商品',
'order_status'=>100, //'100 待付款',
];
$order_items = [
[
'order_item_id'=>$orderId . rand(100, 999),
'order_id'=>$orderId,
'user_id'=>$userId,
'goods_spu_id'=>$orderId . rand(100, 999),
'goods_sku_id'=>$orderId . rand(100, 999),
'marketing_type'=>1,
],
[
'order_item_id'=>$orderId . rand(100, 999),
'order_id'=>$orderId,
'user_id'=>$userId,
'goods_spu_id'=>$orderId . rand(100, 999),
'goods_sku_id'=>$orderId . rand(100, 999),
'marketing_type'=>1,
]
];
foreach ($order_items as $r) {
$order_distribution[] = [
'commission_mode'=>1,
'distributor_user_id'=>122234,
'distributor_commission_value'=>60,
'parent_user_id'=>122234 . rand(111, 999),
'parent_commission_value'=>60,
];
}
return [
'order'=> $order,
'order_items'=> $order_items,
'order_distribution'=> $order_distribution,
];
}
}
\ No newline at end of file
<?php
namespace App\Services\pay;
use Api\PhpServices\Idgen\Idgen;
use App\Exception\custom\PayException;
use App\Models\order\mysql\PayOrder;
use App\Models\order\mysql\PayOrderClearing;
class PayService
{
public function do_pay($order_id, $user_id) {
// 判断是否存在有效订单
$this->exist_valid($order_id, $user_id);
// 获取订单信息 + 子单信息 + 分润信息
$data = $this->get_order_data($order_id, $user_id);
// 创建订单信息
$pay_order = $this->make_pay_order($data);
// 发送ping++ 创建支付订单
$this->send_pingxx($pay_order);
}
/**
* @param $order_id
* @param $user_id
* @throws PayException
* 判断是否有效订单,如果存在则调用三方判断订单状态
*/
private function exist_valid($order_id, $user_id) {
$cur_date = date('Y-m-d H:i:s');
$order = PayOrder::ge(["order_id" => $order_id, 'expire_time[>]'=>$cur_date]);
if(!empty($order)) {
if($order['user_id'] != $user_id) {
throw new PayException(['cus' => 1]);
}
if(empty($order['third_order_id'])) {
throw new PayException(['cus' => 2]);
}
$this->get_order_from_pingxx($order['third_order_id']);
}
}
private function get_order_data($order_id, $user_id) {
}
public function makePayOrder($data) {
}
public function getInfo($orderId) {
$order = PayOrder::getRecord(["order_id" => $orderId]);
`expire_time` timestamp NULL DEFAULT NULL COMMENT '支付订单过期时间',
pay_order_status
}
public function iPingCreate() {
}
/**
* 创建店铺,同时更新生活号表的店铺数
* @param $life_account_id
* @param $merchant_id
* @param string $name
* @param bool $audit 是否需要审核
* @return \Api\PhpUtils\Mysql\MysqlBase
* @throws LifeAccountException
*/
public function create($life_account_id, $merchant_id, $name='', $shop_status=Shop::SHOP_STATUS_ON){
$life = LifeAccount::getMaster(['life_account_name'],['life_account_id' => $life_account_id]);
if(empty($life)){
throw new LifeAccountException(['cus'=>2]);
}
// 店铺id,通过idgen生成
$shop_id = OrderService::get_idgen_id(substr($life_account_id, -2));
$shop_id = $shop_id[0] ?? '';
if(empty($shop_id)){
throw new ShopException(['cus'=>1]);
}
// 店铺名,默认同生活号名
if(empty($name)){
$name = $life['life_account_name'];
}
$shop_res = Shop::insertRecord([
'shop_id' => $shop_id,
'shop_name' => $name,
'merchant_id' => $merchant_id,
'life_account_id' => $life_account_id,
'shop_status' => $shop_status
]);
if($shop_res===false){
throw new ShopException(['cus'=>0]);
}
// 更新生活号店铺数
$shop_res2 = LifeAccount::update([
"shop_totel_count[+]" => 1,
"shop_count[+]" => 1,
],[
"life_account_id" => $life_account_id
]);
if(!$shop_res2){
throw new ShopException(['cus'=>2]);
}
return $shop_id;
}
/**
* 更新商户id
*/
public static function changeMid($o_mid, $n_mid){
$res = Shop::update([
'merchant_id' => $n_mid
],[
'merchant_id' => $o_mid
]);
if($res===false){
throw new ShopException(['cus'=>3]);
}
return true;
}
}
\ No newline at end of file
## 业务处理放在这里
\ No newline at end of file
{
"name" : "bp/pay",
"description": "",
"type": "project",
"license": "MIT",
"require": {
"php": "7.4.*",
"ext-json": "*",
"api/php_utils":"dev-master",
"api/php_services":"dev-master",
"ext-openssl": "*"
},
"minimum-stability": "dev",
"autoload" : {
"psr-4" : {
"App\\Plugins\\" : "application/plugins",
"App\\Services\\" : "application/services",
"App\\Models\\" : "application/models",
"App\\Base\\" : "application/modules/Base",
"App\\Exception\\" : "application/exception",
"Daemon\\" : "daemon"
}
},
"scripts": {
"post-update-cmd": [
"php -f rmgit.php"
]
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"repositories": {
"api/php_utils":{
"type":"vcs",
"url":"https://gitlab.yidian-inc.com/bp/php_utils.git"
},
"api/php_services":{
"type":"vcs",
"url":"https://gitlab.yidian-inc.com/bp/php_services.git"
}
}
}
\ No newline at end of file
[common]
application.directory = APP_PATH
application.bootstrap = APP_PATH "/Bootstrap.php"
application.library = APP_PATH"/library"
application.library.namespace = ""
application.modules="Index,Test,Pay,Refund"
appid = "pay"
;AES密钥
aes.key = "79b20206d70e09b2"
aes.iv = "645410b05b5d1670"
aes.timeout = 5
;校验时间的开关
aes.switch = true
idgen.partner = "bp"
idgen.key = "5cfdb867e96374c7883b31d6928cc4cb"
[exception]
debug = true
exception.user.code = -1
exception.user.msg = "error"
exception.sys.code = -1
exception.sys.msg = "system error"
[prod : common : exception]
[pre : common : exception]
[test : common : exception]
[dev : common : exception]
[common]
application.directory = APPLICATION_PATH"/application"
application.library = APPLICATION_PATH"/application/library"
application.bootstrap = APPLICATION_PATH"/application/BootstrapCli.php"
application.dispatcher.catchException = true
application.dispatcher.throwException = true
daemon.script_dir = "\\Daemon\\"
appid = "pay"
[product : common]
[pre : common ]
[test: common ]
[dev : common ]
\ No newline at end of file
<?php
namespace Daemon;
use Api\PhpServices\Daemon\DaemonServiceInterface;
class Test implements DaemonServiceInterface
{
public function run()
{
// throw new \Exception("test exception");
sleep(10);
}
}
\ No newline at end of file
ipdata等文件放在这里
\ No newline at end of file
#!/usr/bin/env bash
# Start commands for each container, one cmd a line
START_CMDS="cd /home/services && ${start_cmd}
"
# QA_PRE_START_CMD='
# export collect_coverage=true
# '
# Container names for each container, one name a line, same order with $start_cmds
CONTAINER_NAMES="
api-${env}-${domain_prefix}
"
# Port maps for each container, one map a line, same order with $start_cmds
DOCKER_PORT_MAPS="
${TARGET_PORT}:9000
"
# This is for changing container name, remove old containers when deploy new one
OLD_CONTAINER_NAMES="
api-${env}-${domain_prefix}
"
# Volumn maps for each container, one map a line, same order with $start_cmds
DOCKER_VOLUMN_MAPS="
/home/worker/_logs/api-${env}-${domain_prefix}:/home/services/api.go2yd.com/logs
"
# Other docker run options
DOCKER_RUN_OPTIONS="--cap-add SYS_PTRACE --restart=always --privileged"
# Image name
IMAGE_NAME="docker2.yidian.com:5000/publish/${COMMIT_JOB}-${COMMIT_NUMBER}-image"
# This is for stopping container, kill sepicify process inside the container before 'docker stop' and 'docker rm'
DOCKER_PRESTOP_CMD='mv /var/lib/logrotate.status /home/services/api.go2yd.com/logs/logrotate.status'
# Service port for apitest
SERVICE_PORT=${TARGET_PORT}
# Service port inside container
ORIGIN_SERVICE_PORT="9000"
#!/usr/bin/env bash
# Start commands for each container, one cmd a line
START_CMDS="
cd /home/services && ${start_cmd}
"
QA_PRE_START_CMD="
"
# Container names for each container, one name a line, same order with $start_cmds
CONTAINER_NAMES="
api-${env}-${domain_prefix}
"
# Port maps for each container, one map a line, same order with $start_cmds
DOCKER_PORT_MAPS="
${TARGET_PORT}:9000
"
# This is for changing container name, remove old containers when deploy new one
OLD_CONTAINER_NAMES="
api-${env}-${domain_prefix}
"
# Volumn maps for each container, one map a line, same order with $start_cmds
DOCKER_VOLUMN_MAPS="
/home/worker/_logs/api-${env}-${domain_prefix}:/home/services/api.go2yd.com/logs
"
# Other docker run options
DOCKER_RUN_OPTIONS="--cap-add SYS_PTRACE --restart=always --privileged"
# Image name
IMAGE_NAME="docker2.yidian.com:5000/publish/${COMMIT_JOB}-${COMMIT_NUMBER}-image"
# This is for stopping container, kill sepicify process inside the container before 'docker stop' and 'docker rm'
DOCKER_PRESTOP_CMD='mv /var/lib/logrotate.status /home/services/api.go2yd.com/logs/logrotate.status'
# Service port for apitest
SERVICE_PORT=${TARGET_PORT}
# Service port inside container
ORIGIN_SERVICE_PORT="9000"
#!/usr/bin/env bash
# Start commands for each container, one cmd a line
START_CMDS="
cd /home/services && ${start_cmd}
"
QA_PRE_START_CMD="
"
# Container names for each container, one name a line, same order with $start_cmds
CONTAINER_NAMES="
api-${env}-${domain_prefix}
"
# Port maps for each container, one map a line, same order with $start_cmds
DOCKER_PORT_MAPS="
${TARGET_PORT}:9000
"
# This is for changing container name, remove old containers when deploy new one
OLD_CONTAINER_NAMES="
api-${env}-${domain_prefix}
"
# Volumn maps for each container, one map a line, same order with $start_cmds
DOCKER_VOLUMN_MAPS="
/home/worker/_logs/api-${env}-${domain_prefix}:/home/services/api.go2yd.com/logs
"
# Other docker run options
DOCKER_RUN_OPTIONS="--cap-add SYS_PTRACE --restart=always --privileged"
# Image name
IMAGE_NAME="docker2.yidian.com:5000/publish/${release_job}-${release_number}-image"
# This is for stopping container, kill sepicify process inside the container before 'docker stop' and 'docker rm'
DOCKER_PRESTOP_CMD='mv /var/lib/logrotate.status /home/services/api.go2yd.com/logs/logrotate.status'
# Service port for apitest
SERVICE_PORT=${TARGET_PORT}
# Service port inside container
ORIGIN_SERVICE_PORT="9000"
#!/usr/bin/env bash
# Start commands for each container, one cmd a line
START_CMDS="cd /home/services && ${start_cmd}
"
# QA_PRE_START_CMD='
# export collect_coverage=true
# '
# Container names for each container, one name a line, same order with $start_cmds
CONTAINER_NAMES="
api-${env}-${domain_prefix}
"
# Port maps for each container, one map a line, same order with $start_cmds
DOCKER_PORT_MAPS="
${TARGET_PORT}:9000
"
# This is for changing container name, remove old containers when deploy new one
OLD_CONTAINER_NAMES="
api-${env}-${domain_prefix}
"
# Volumn maps for each container, one map a line, same order with $start_cmds
DOCKER_VOLUMN_MAPS="
/home/worker/_logs/api-${env}-${domain_prefix}:/home/services/api.go2yd.com/logs
"
# Other docker run options
DOCKER_RUN_OPTIONS="--cap-add SYS_PTRACE --restart=always --privileged"
# Image name
IMAGE_NAME="docker2.yidian.com:5000/publish/${COMMIT_JOB}-${COMMIT_NUMBER}-image"
# This is for stopping container, kill sepicify process inside the container before 'docker stop' and 'docker rm'
DOCKER_PRESTOP_CMD='mv /var/lib/logrotate.status /home/services/api.go2yd.com/logs/logrotate.status'
# Service port for apitest
SERVICE_PORT=${TARGET_PORT}
# Service port inside container
ORIGIN_SERVICE_PORT="9000"
#!/usr/bin/env bash
DIST_FILE_NAME="*.tar.gz"
PROJECT_DIR="api.go2yd.com"
START_SCRIPT="./start_env/start_api.sh"
SYNC_DATA_OPERATIONS="
tar zxf *.tar.gz -C start_env/api.go2yd.com/htdocs/Website
"
DEST_FILE_NAME=""
DEST_FILE_PATH=""
BASE_IMAGE="docker2.yidian.com:5000/centos7/php72_without_nginx:20210621"
MAINTAINER="cuiweifeng \"cuiweifeng@yidian-inc.com\""
HOME_DIR="/home/services"
LOG_DIRS="
${HOME_DIR}/${PROJECT_DIR}/logs
"
DATA_DIRS="
"
#!/usr/bin/env bash
DIST_FILE_NAME="*.tar.gz"
PROJECT_DIR="api.go2yd.com"
START_SCRIPT="./start_env/start_api.sh"
SYNC_DATA_OPERATIONS="
tar zxf *.tar.gz -C start_env/api.go2yd.com/htdocs/Website
"
DEST_FILE_NAME=""
DEST_FILE_PATH=""
BASE_IMAGE="docker2.yidian.com:5000/centos7/php72_without_nginx:20210621"
MAINTAINER="cuiweifeng \"cuiweifeng@yidian-inc.com\""
HOME_DIR="/home/services"
LOG_DIRS="
${HOME_DIR}/${PROJECT_DIR}/logs
"
DATA_DIRS="
"
#!/usr/bin/env bash
DIST_FILE_NAME="*.tar.gz"
PROJECT_DIR="api.go2yd.com"
START_SCRIPT="./start_env/start_api.sh"
SYNC_DATA_OPERATIONS="
tar zxf *.tar.gz -C start_env/api.go2yd.com/htdocs/Website
"
DEST_FILE_NAME=""
DEST_FILE_PATH=""
BASE_IMAGE="docker2.yidian.com:5000/centos7/php72_without_nginx:20210621"
MAINTAINER="cuiweifeng \"cuiweifeng@yidian-inc.com\""
HOME_DIR="/home/services"
LOG_DIRS="
${HOME_DIR}/${PROJECT_DIR}/logs
"
DATA_DIRS="
"
#!/usr/bin/env bash
DIST_FILE_NAME="*.tar.gz"
PROJECT_DIR="api.go2yd.com"
START_SCRIPT="./start_env/start_api.sh"
SYNC_DATA_OPERATIONS="
tar zxf *.tar.gz -C start_env/api.go2yd.com/htdocs/Website
"
DEST_FILE_NAME=""
DEST_FILE_PATH=""
BASE_IMAGE="docker2.yidian.com:5000/centos7/php72_without_nginx:20210621"
MAINTAINER="cuiweifeng \"cuiweifeng@yidian-inc.com\""
HOME_DIR="/home/services"
LOG_DIRS="
${HOME_DIR}/${PROJECT_DIR}/logs
"
DATA_DIRS="
"
<?php
/*
+----------------------------------------------------------------------+
| APC |
+----------------------------------------------------------------------+
| Copyright (c) 2006-2011 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Ralf Becker <beckerr@php.net> |
| Rasmus Lerdorf <rasmus@php.net> |
| Ilia Alshanetsky <ilia@prohost.org> |
+----------------------------------------------------------------------+
All other licensing and usage conditions are those of the PHP Group.
*/
if( !isset($_GET['token']) || $_GET['token'] != 'cc47179dffd7e23de9e6eb62d714afd3' )
{
die;
}
$extra_params = "ip=".$_GET['ip']."&type=".$_GET['type']."&token=".$_GET['token'];
// var_dump($_GET);
$VERSION = '$Id$';
////////// READ OPTIONAL CONFIGURATION FILE ////////////
if (file_exists("apc.conf.php")) include("apc.conf.php");
////////////////////////////////////////////////////////
////////// BEGIN OF DEFAULT CONFIG AREA ///////////////////////////////////////////////////////////
defaults('USE_AUTHENTICATION', 1); // Use (internal) authentication - best choice if
// no other authentication is available
// If set to 0:
// There will be no further authentication. You
// will have to handle this by yourself!
// If set to 1:
// You need to change ADMIN_PASSWORD to make
// this work!
defaults('ADMIN_USERNAME', 'apc'); // Admin Username
defaults('ADMIN_PASSWORD', 'apc'); // Admin Password - CHANGE THIS TO ENABLE!!!
// (beckerr) I'm using a clear text password here, because I've no good idea how to let
// users generate a md5 or crypt password in a easy way to fill it in above
//defaults('DATE_FORMAT', "d.m.Y H:i:s"); // German
defaults('DATE_FORMAT', 'Y/m/d H:i:s'); // US
defaults('GRAPH_SIZE', 200); // Image size
//defaults('PROXY', 'tcp://127.0.0.1:8080');
////////// END OF DEFAULT CONFIG AREA /////////////////////////////////////////////////////////////
// "define if not defined"
function defaults($d, $v)
{
if (!defined($d)) define($d, $v); // or just @define(...)
}
// rewrite $PHP_SELF to block XSS attacks
//
$PHP_SELF = isset($_SERVER['PHP_SELF']) ? htmlentities(strip_tags($_SERVER['PHP_SELF'], ''), ENT_QUOTES, 'UTF-8') : '';
if(strpos($PHP_SELF,'type') === false)
{
$PHP_SELF = $PHP_SELF . "?" . $extra_params;
}
$time = time();
$host = php_uname('n');
if ($host) {
$host = '(' . $host . ')';
}
if (isset($_SERVER['SERVER_ADDR'])) {
$host .= ' (' . $_SERVER['SERVER_ADDR'] . ')';
}
// operation constants
define('OB_HOST_STATS', 1);
define('OB_USER_CACHE', 2);
define('OB_VERSION_CHECK', 3);
// check validity of input variables
$vardom = array(
'OB' => '/^\d+$/', // operational mode switch
'CC' => '/^[01]$/', // clear cache requested
'DU' => '/^.*$/', // Delete User Key
'SH' => '/^[a-z0-9]+$/', // shared object description
'IMG' => '/^[123]$/', // image to generate
'LO' => '/^1$/', // login requested
'COUNT' => '/^\d+$/', // number of line displayed in list
'SCOPE' => '/^[AD]$/', // list view scope
'SORT1' => '/^[AHSMCDTZ]$/', // first sort key
'SORT2' => '/^[DA]$/', // second sort key
'AGGR' => '/^\d+$/', // aggregation by dir level
'SEARCH' => '~^[a-zA-Z0-9/_.-]*$~' // aggregation by dir level
);
// cache scope
$scope_list = array(
'A' => 'cache_list',
'D' => 'deleted_list'
);
// handle POST and GET requests
if (empty($_REQUEST)) {
if (!empty($_GET) && !empty($_POST)) {
$_REQUEST = array_merge($_GET, $_POST);
} else if (!empty($_GET)) {
$_REQUEST = $_GET;
} else if (!empty($_POST)) {
$_REQUEST = $_POST;
} else {
$_REQUEST = array();
}
}
// check parameter syntax
foreach ($vardom as $var => $dom) {
if (!isset($_REQUEST[$var])) {
$MYREQUEST[$var] = NULL;
} else if (!is_array($_REQUEST[$var]) && preg_match($dom . 'D', $_REQUEST[$var])) {
$MYREQUEST[$var] = $_REQUEST[$var];
} else {
$MYREQUEST[$var] = $_REQUEST[$var] = NULL;
}
}
// check parameter sematics
if (empty($MYREQUEST['SCOPE'])) $MYREQUEST['SCOPE'] = "A";
if (empty($MYREQUEST['SORT1'])) $MYREQUEST['SORT1'] = "H";
if (empty($MYREQUEST['SORT2'])) $MYREQUEST['SORT2'] = "D";
if (empty($MYREQUEST['OB'])) $MYREQUEST['OB'] = OB_HOST_STATS;
if (!isset($MYREQUEST['COUNT'])) $MYREQUEST['COUNT'] = 20;
if (!isset($scope_list[$MYREQUEST['SCOPE']])) $MYREQUEST['SCOPE'] = 'A';
$MY_SELF =
"$PHP_SELF" .
"&SCOPE=" . $MYREQUEST['SCOPE'] .
"&SORT1=" . $MYREQUEST['SORT1'] .
"&SORT2=" . $MYREQUEST['SORT2'] .
"&COUNT=" . $MYREQUEST['COUNT'];
// if(strpos($MY_SELF,'type') === false)
// {
// $MY_SELF = $MY_SELF . "&" . $extra_params;
// }
$MY_SELF_WO_SORT =
"$PHP_SELF" .
"&SCOPE=" . $MYREQUEST['SCOPE'] .
"&COUNT=" . $MYREQUEST['COUNT'];
if(strpos($MY_SELF_WO_SORT,'type') === false)
{
$MY_SELF_WO_SORT = $MY_SELF_WO_SORT . "&" . $extra_params;
}
// authentication needed?
//
if (!USE_AUTHENTICATION) {
$AUTHENTICATED = 1;
} else {
$AUTHENTICATED = 0;
if (ADMIN_PASSWORD != 'password' && ($MYREQUEST['LO'] == 1 || isset($_SERVER['PHP_AUTH_USER']))) {
if (!isset($_SERVER['PHP_AUTH_USER']) ||
!isset($_SERVER['PHP_AUTH_PW']) ||
$_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||
$_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD
) {
Header("WWW-Authenticate: Basic realm=\"APC Login\"");
Header("HTTP/1.0 401 Unauthorized");
echo <<<EOB
<html><body>
<h1>Rejected!</h1>
<big>Wrong Username or Password!</big><br/>&nbsp;<br/>&nbsp;
<big><a href='$PHP_SELF&OB={$MYREQUEST['OB']}'>Continue...</a></big>
</body></html>
EOB;
exit;
} else {
$AUTHENTICATED = 1;
}
}
}
// clear cache
if ($AUTHENTICATED && isset($MYREQUEST['CC']) && $MYREQUEST['CC']) {
apcu_clear_cache();
}
if ($AUTHENTICATED && !empty($MYREQUEST['DU'])) {
apcu_delete($MYREQUEST['DU']);
}
if (!function_exists('apcu_cache_info')) {
echo "No cache info available. APC does not appear to be running.";
exit;
}
$cache = apcu_cache_info();
$mem = apcu_sma_info();
// don't cache this page
//
header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache"); // HTTP/1.0
function duration($ts)
{
global $time;
$years = (int)((($time - $ts) / (7 * 86400)) / 52.177457);
$rem = (int)(($time - $ts) - ($years * 52.177457 * 7 * 86400));
$weeks = (int)(($rem) / (7 * 86400));
$days = (int)(($rem) / 86400) - $weeks * 7;
$hours = (int)(($rem) / 3600) - $days * 24 - $weeks * 7 * 24;
$mins = (int)(($rem) / 60) - $hours * 60 - $days * 24 * 60 - $weeks * 7 * 24 * 60;
$str = '';
if ($years == 1) $str .= "$years year, ";
if ($years > 1) $str .= "$years years, ";
if ($weeks == 1) $str .= "$weeks week, ";
if ($weeks > 1) $str .= "$weeks weeks, ";
if ($days == 1) $str .= "$days day,";
if ($days > 1) $str .= "$days days,";
if ($hours == 1) $str .= " $hours hour and";
if ($hours > 1) $str .= " $hours hours and";
if ($mins == 1) $str .= " 1 minute";
else $str .= " $mins minutes";
return $str;
}
// create graphics
//
function graphics_avail()
{
return extension_loaded('gd');
}
if (isset($MYREQUEST['IMG'])) {
if (!graphics_avail()) {
exit(0);
}
function fill_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1, $color2, $text = '', $placeindex = 0)
{
$r = $diameter / 2;
$w = deg2rad((360 + $start + ($end - $start) / 2) % 360);
if (function_exists("imagefilledarc")) {
// exists only if GD 2.0.1 is avaliable
imagefilledarc($im, $centerX + 1, $centerY + 1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE);
imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2, IMG_ARC_PIE);
imagefilledarc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color1, IMG_ARC_NOFILL | IMG_ARC_EDGED);
} else {
imagearc($im, $centerX, $centerY, $diameter, $diameter, $start, $end, $color2);
imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($start + 1)) * $r, $centerY + sin(deg2rad($start)) * $r, $color2);
imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end - 1)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
imageline($im, $centerX, $centerY, $centerX + cos(deg2rad($end)) * $r, $centerY + sin(deg2rad($end)) * $r, $color2);
imagefill($im, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $color2);
}
if ($text) {
if ($placeindex > 0) {
imageline($im, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $diameter, $placeindex * 12, $color1);
imagestring($im, 4, $diameter, $placeindex * 12, $text, $color1);
} else {
imagestring($im, 4, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $text, $color1);
}
}
}
function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1, $text, $placeindex = 0)
{
$r = $diameter / 2;
$w = deg2rad((360 + $start + ($end - $start) / 2) % 360);
if ($placeindex > 0) {
imageline($im, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $diameter, $placeindex * 12, $color1);
imagestring($im, 4, $diameter, $placeindex * 12, $text, $color1);
} else {
imagestring($im, 4, $centerX + $r * cos($w) / 2, $centerY + $r * sin($w) / 2, $text, $color1);
}
}
function fill_box($im, $x, $y, $w, $h, $color1, $color2, $text = '', $placeindex = '')
{
global $col_black;
$x1 = $x + $w - 1;
$y1 = $y + $h - 1;
imagerectangle($im, $x, $y1, $x1 + 1, $y + 1, $col_black);
if ($y1 > $y) imagefilledrectangle($im, $x, $y, $x1, $y1, $color2);
else imagefilledrectangle($im, $x, $y1, $x1, $y, $color2);
imagerectangle($im, $x, $y1, $x1, $y, $color1);
if ($text) {
if ($placeindex > 0) {
if ($placeindex < 16) {
$px = 5;
$py = $placeindex * 12 + 6;
imagefilledrectangle($im, $px + 90, $py + 3, $px + 90 - 4, $py - 3, $color2);
imageline($im, $x, $y + $h / 2, $px + 90, $py, $color2);
imagestring($im, 2, $px, $py - 6, $text, $color1);
} else {
if ($placeindex < 31) {
$px = $x + 40 * 2;
$py = ($placeindex - 15) * 12 + 6;
} else {
$px = $x + 40 * 2 + 100 * intval(($placeindex - 15) / 15);
$py = ($placeindex % 15) * 12 + 6;
}
imagefilledrectangle($im, $px, $py + 3, $px - 4, $py - 3, $color2);
imageline($im, $x + $w, $y + $h / 2, $px, $py, $color2);
imagestring($im, 2, $px + 2, $py - 6, $text, $color1);
}
} else {
imagestring($im, 4, $x + 5, $y1 - 16, $text, $color1);
}
}
}
$size = GRAPH_SIZE; // image size
if ($MYREQUEST['IMG'] == 3)
$image = imagecreate(2 * $size + 150, $size + 10);
else
$image = imagecreate($size + 50, $size + 10);
$col_white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
$col_red = imagecolorallocate($image, 0xD0, 0x60, 0x30);
$col_green = imagecolorallocate($image, 0x60, 0xF0, 0x60);
$col_black = imagecolorallocate($image, 0, 0, 0);
imagecolortransparent($image, $col_white);
switch ($MYREQUEST['IMG']) {
case 1:
$s = $mem['num_seg'] * $mem['seg_size'];
$a = $mem['avail_mem'];
$x = $y = $size / 2;
$fuzz = 0.000001;
// This block of code creates the pie chart. It is a lot more complex than you
// would expect because we try to visualize any memory fragmentation as well.
$angle_from = 0;
$string_placement = array();
for ($i = 0; $i < $mem['num_seg']; $i++) {
$ptr = 0;
$free = $mem['block_lists'][$i];
uasort($free, 'block_sort');
foreach ($free as $block) {
if ($block['offset'] != $ptr) { // Used block
$angle_to = $angle_from + ($block['offset'] - $ptr) / $s;
if (($angle_to + $fuzz) > 1) $angle_to = 1;
if (($angle_to * 360) - ($angle_from * 360) >= 1) {
fill_arc($image, $x, $y, $size, $angle_from * 360, $angle_to * 360, $col_black, $col_red);
if (($angle_to - $angle_from) > 0.05) {
array_push($string_placement, array($angle_from, $angle_to));
}
}
$angle_from = $angle_to;
}
$angle_to = $angle_from + ($block['size']) / $s;
if (($angle_to + $fuzz) > 1) $angle_to = 1;
if (($angle_to * 360) - ($angle_from * 360) >= 1) {
fill_arc($image, $x, $y, $size, $angle_from * 360, $angle_to * 360, $col_black, $col_green);
if (($angle_to - $angle_from) > 0.05) {
array_push($string_placement, array($angle_from, $angle_to));
}
}
$angle_from = $angle_to;
$ptr = $block['offset'] + $block['size'];
}
if ($ptr < $mem['seg_size']) { // memory at the end
$angle_to = $angle_from + ($mem['seg_size'] - $ptr) / $s;
if (($angle_to + $fuzz) > 1) $angle_to = 1;
fill_arc($image, $x, $y, $size, $angle_from * 360, $angle_to * 360, $col_black, $col_red);
if (($angle_to - $angle_from) > 0.05) {
array_push($string_placement, array($angle_from, $angle_to));
}
}
}
foreach ($string_placement as $angle) {
text_arc($image, $x, $y, $size, $angle[0] * 360, $angle[1] * 360, $col_black, bsize($s * ($angle[1] - $angle[0])));
}
break;
case 2:
$s = $cache['num_hits'] + $cache['num_misses'];
$a = $cache['num_hits'];
fill_box($image, 30, $size, 50, $s ? (-$a * ($size - 21) / $s) : 0, $col_black, $col_green, sprintf("%.1f%%", $s ? $cache['num_hits'] * 100 / $s : 0));
fill_box($image, 130, $size, 50, $s ? -max(4, ($s - $a) * ($size - 21) / $s) : 0, $col_black, $col_red, sprintf("%.1f%%", $s ? $cache['num_misses'] * 100 / $s : 0));
break;
case 3:
$s = $mem['num_seg'] * $mem['seg_size'];
$a = $mem['avail_mem'];
$x = 130;
$y = 1;
$j = 1;
// This block of code creates the bar chart. It is a lot more complex than you
// would expect because we try to visualize any memory fragmentation as well.
for ($i = 0; $i < $mem['num_seg']; $i++) {
$ptr = 0;
$free = $mem['block_lists'][$i];
uasort($free, 'block_sort');
foreach ($free as $block) {
if ($block['offset'] != $ptr) { // Used block
$h = (GRAPH_SIZE - 5) * ($block['offset'] - $ptr) / $s;
if ($h > 0) {
$j++;
if ($j < 75) fill_box($image, $x, $y, 50, $h, $col_black, $col_red, bsize($block['offset'] - $ptr), $j);
else fill_box($image, $x, $y, 50, $h, $col_black, $col_red);
}
$y += $h;
}
$h = (GRAPH_SIZE - 5) * ($block['size']) / $s;
if ($h > 0) {
$j++;
if ($j < 75) fill_box($image, $x, $y, 50, $h, $col_black, $col_green, bsize($block['size']), $j);
else fill_box($image, $x, $y, 50, $h, $col_black, $col_green);
}
$y += $h;
$ptr = $block['offset'] + $block['size'];
}
if ($ptr < $mem['seg_size']) { // memory at the end
$h = (GRAPH_SIZE - 5) * ($mem['seg_size'] - $ptr) / $s;
if ($h > 0) {
fill_box($image, $x, $y, 50, $h, $col_black, $col_red, bsize($mem['seg_size'] - $ptr), $j++);
}
}
}
break;
case 4:
$s = $cache['num_hits'] + $cache['num_misses'];
$a = $cache['num_hits'];
fill_box($image, 30, $size, 50, $s ? -$a * ($size - 21) / $s : 0, $col_black, $col_green, sprintf("%.1f%%", $s ? $cache['num_hits'] * 100 / $s : 0));
fill_box($image, 130, $size, 50, $s ? -max(4, ($s - $a) * ($size - 21) / $s) : 0, $col_black, $col_red, sprintf("%.1f%%", $s ? $cache['num_misses'] * 100 / $s : 0));
break;
}
header("Content-type: image/png");
imagepng($image);
exit;
}
// pretty printer for byte values
//
function bsize($s)
{
foreach (array('', 'K', 'M', 'G') as $i => $k) {
if ($s < 1024) break;
$s /= 1024;
}
return sprintf("%5.1f %sBytes", $s, $k);
}
// sortable table header in "scripts for this host" view
function sortheader($key, $name, $extra = '')
{
global $MYREQUEST, $MY_SELF_WO_SORT;
if ($MYREQUEST['SORT1'] == $key) {
$MYREQUEST['SORT2'] = $MYREQUEST['SORT2'] == 'A' ? 'D' : 'A';
}
return "<a class=sortable href=\"$MY_SELF_WO_SORT$extra&SORT1=$key&SORT2=" . $MYREQUEST['SORT2'] . "\">$name</a>";
}
// var_dump($extra_params);
// create menu entry
function menu_entry($ob, $title)
{
global $MYREQUEST, $MY_SELF, $extra_params;
if ($MYREQUEST['OB'] != $ob) {
return "<li><a href=\"$MY_SELF&OB=$ob\">$title</a></li>";
} else if (empty($MYREQUEST['SH'])) {
return "<li><span class=active>$title</span></li>";
} else {
return "<li><a class=\"child_active\" href=\"$MY_SELF&OB=$ob\">$title</a></li>";
}
}
function put_login_link($s = "Login")
{
global $MY_SELF, $MYREQUEST, $AUTHENTICATED, $extra_params;
// needs ADMIN_PASSWORD to be changed!
//
if (!USE_AUTHENTICATION) {
return;
} else if (ADMIN_PASSWORD == 'password') {
print <<<EOB
<a href="#" onClick="javascript:alert('You need to set a password at the top of apc.php before this will work!');return false";>$s</a>
EOB;
} else if ($AUTHENTICATED) {
print <<<EOB
'{$_SERVER['PHP_AUTH_USER']}'&nbsp;logged&nbsp;in!
EOB;
} else {
print <<<EOB
<a href="$MY_SELF&LO=1&OB={$MYREQUEST['OB']}">$s</a>
EOB;
}
}
function block_sort($array1, $array2)
{
if ($array1['offset'] > $array2['offset']) {
return 1;
} else {
return -1;
}
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>APCu INFO <?php echo $host ?></title>
<style><!--
body {
background: white;
font-size: 100.01%;
margin: 0;
padding: 0;
}
body, p, td, th, input, submit {
font-size: 0.8em;
font-family: arial, helvetica, sans-serif;
}
* html body {
font-size: 0.8em
}
* html p {
font-size: 0.8em
}
* html td {
font-size: 0.8em
}
* html th {
font-size: 0.8em
}
* html input {
font-size: 0.8em
}
* html submit {
font-size: 0.8em
}
td {
vertical-align: top
}
a {
color: black;
font-weight: none;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
div.content {
padding: 1em 1em 1em 1em;
position: absolute;
width: 97%;
z-index: 100;
}
div.head div.login {
position: absolute;
right: 1em;
top: 1.2em;
color: white;
width: 6em;
}
div.head div.login a {
position: absolute;
right: 0em;
background: rgb(119, 123, 180);
border: solid rgb(102, 102, 153) 2px;
color: white;
font-weight: bold;
padding: 0.1em 0.5em 0.1em 0.5em;
text-decoration: none;
}
div.head div.login a:hover {
background: rgb(193, 193, 244);
}
h1.apc {
background: rgb(153, 153, 204);
margin: 0;
padding: 0.5em 1em 0.5em 1em;
}
* html h1.apc {
margin-bottom: -7px;
}
h1.apc a:hover {
text-decoration: none;
color: rgb(90, 90, 90);
}
h1.apc div.logo span.logo {
background: rgb(119, 123, 180);
color: black;
border-right: solid black 1px;
border-bottom: solid black 1px;
font-style: italic;
font-size: 1em;
padding-left: 1.2em;
padding-right: 1.2em;
text-align: right;
}
h1.apc div.logo span.name {
color: white;
font-size: 0.7em;
padding: 0 0.8em 0 2em;
}
h1.apc div.nameinfo {
color: white;
display: inline;
font-size: 0.4em;
margin-left: 3em;
}
h1.apc div.copy {
color: black;
font-size: 0.4em;
position: absolute;
right: 1em;
}
hr.apc {
background: white;
border-bottom: solid rgb(102, 102, 153) 1px;
border-style: none;
border-top: solid rgb(102, 102, 153) 10px;
height: 12px;
margin: 0;
margin-top: 1px;
padding: 0;
}
ol, menu {
margin: 1em 0 0 0;
padding: 0.2em;
margin-left: 1em;
}
ol.menu li {
display: inline;
margin-right: 0.7em;
list-style: none;
font-size: 85%
}
ol.menu a {
background: rgb(153, 153, 204);
border: solid rgb(102, 102, 153) 2px;
color: white;
font-weight: bold;
margin-right: 0em;
padding: 0.1em 0.5em 0.1em 0.5em;
text-decoration: none;
margin-left: 5px;
}
ol.menu a.child_active {
background: rgb(153, 153, 204);
border: solid rgb(102, 102, 153) 2px;
color: white;
font-weight: bold;
margin-right: 0em;
padding: 0.1em 0.5em 0.1em 0.5em;
text-decoration: none;
border-left: solid black 5px;
margin-left: 0px;
}
ol.menu span.active {
background: rgb(153, 153, 204);
border: solid rgb(102, 102, 153) 2px;
color: black;
font-weight: bold;
margin-right: 0em;
padding: 0.1em 0.5em 0.1em 0.5em;
text-decoration: none;
border-left: solid black 5px;
}
ol.menu span.inactive {
background: rgb(193, 193, 244);
border: solid rgb(182, 182, 233) 2px;
color: white;
font-weight: bold;
margin-right: 0em;
padding: 0.1em 0.5em 0.1em 0.5em;
text-decoration: none;
margin-left: 5px;
}
ol.menu a:hover {
background: rgb(193, 193, 244);
text-decoration: none;
}
div.info {
background: rgb(204, 204, 204);
border: solid rgb(204, 204, 204) 1px;
margin-bottom: 1em;
}
div.info h2 {
background: rgb(204, 204, 204);
color: black;
font-size: 1em;
margin: 0;
padding: 0.1em 1em 0.1em 1em;
}
div.info table {
border: solid rgb(204, 204, 204) 1px;
border-spacing: 0;
width: 100%;
}
div.info table th {
background: rgb(204, 204, 204);
color: white;
margin: 0;
padding: 0.1em 1em 0.1em 1em;
}
div.info table th a.sortable {
color: black;
}
div.info table tr.tr-0 {
background: rgb(238, 238, 238);
}
div.info table tr.tr-1 {
background: rgb(221, 221, 221);
}
div.info table td {
padding: 0.3em 1em 0.3em 1em;
}
div.info table td.td-0 {
border-right: solid rgb(102, 102, 153) 1px;
white-space: nowrap;
}
div.info table td.td-n {
border-right: solid rgb(102, 102, 153) 1px;
}
div.info table td h3 {
color: black;
font-size: 1.1em;
margin-left: -0.3em;
}
div.graph {
margin-bottom: 1em
}
div.graph h2 {
background: rgb(204, 204, 204);;
color: black;
font-size: 1em;
margin: 0;
padding: 0.1em 1em 0.1em 1em;
}
div.graph table {
border: solid rgb(204, 204, 204) 1px;
color: black;
font-weight: normal;
width: 100%;
}
div.graph table td.td-0 {
background: rgb(238, 238, 238);
}
div.graph table td.td-1 {
background: rgb(221, 221, 221);
}
div.graph table td {
padding: 0.2em 1em 0.4em 1em;
}
div.div1, div.div2 {
margin-bottom: 1em;
width: 35em;
}
div.div3 {
position: absolute;
left: 40em;
top: 1em;
width: 580px;
}
/
/
div.div3 {
position: absolute;
left: 37em;
top: 1em;
right: 1em;
}
div.sorting {
margin: 1.5em 0em 1.5em 2em
}
.center {
text-align: center
}
.aright {
position: absolute;
right: 1em
}
.right {
text-align: right
}
.ok {
color: rgb(0, 200, 0);
font-weight: bold
}
.failed {
color: rgb(200, 0, 0);
font-weight: bold
}
span.box {
border: black solid 1px;
border-right: solid black 2px;
border-bottom: solid black 2px;
padding: 0 0.5em 0 0.5em;
margin-right: 1em;
}
span.green {
background: #60F060;
padding: 0 0.5em 0 0.5em
}
span.red {
background: #D06030;
padding: 0 0.5em 0 0.5em
}
div.authneeded {
background: rgb(238, 238, 238);
border: solid rgb(204, 204, 204) 1px;
color: rgb(200, 0, 0);
font-size: 1.2em;
font-weight: bold;
padding: 2em;
text-align: center;
}
input {
background: rgb(153, 153, 204);
border: solid rgb(102, 102, 153) 2px;
color: white;
font-weight: bold;
margin-right: 1em;
padding: 0.1em 0.5em 0.1em 0.5em;
}
/
/
-->
</style>
</head>
<body>
<div class="head">
<h1 class="apc">
<div class="logo"><span class="logo"><a href="http://pecl.php.net/package/APCu">APCu</a></span></div>
<div class="nameinfo">User Cache</div>
</h1>
<div class="login">
<?php put_login_link(); ?>
</div>
<hr class="apc">
</div>
<?php
// Display main Menu
echo <<<EOB
<ol class=menu>
<li><a href="$MY_SELF&OB={$MYREQUEST['OB']}&SH={$MYREQUEST['SH']}">Refresh Data</a></li>
EOB;
echo
menu_entry(OB_HOST_STATS, 'View Host Stats'),
menu_entry(OB_USER_CACHE, 'User Cache Entries'),
menu_entry(OB_VERSION_CHECK, 'Version Check');
if ($AUTHENTICATED) {
echo <<<EOB
<li><a class="aright" href="$MY_SELF&CC=1&OB={$MYREQUEST['OB']}" onClick="javascript:return confirm('Are you sure?');">Clear Cache</a></li>
EOB;
}
echo <<<EOB
</ol>
EOB;
// CONTENT
echo <<<EOB
<div class=content>
EOB;
// MAIN SWITCH STATEMENT
//var_dump($PHP_SELF);
switch ($MYREQUEST['OB']) {
// -----------------------------------------------
// Host Stats
// -----------------------------------------------
case OB_HOST_STATS:
$mem_size = $mem['num_seg'] * $mem['seg_size'];
$mem_avail = $mem['avail_mem'];
$mem_used = $mem_size - $mem_avail;
$seg_size = bsize($mem['seg_size']);
$req_rate_user = sprintf("%.2f", $cache['num_hits'] ? (($cache['num_hits'] + $cache['num_misses']) / ($time - $cache['start_time'])) : 0);
$hit_rate_user = sprintf("%.2f", $cache['num_hits'] ? (($cache['num_hits']) / ($time - $cache['start_time'])) : 0);
$miss_rate_user = sprintf("%.2f", $cache['num_misses'] ? (($cache['num_misses']) / ($time - $cache['start_time'])) : 0);
$insert_rate_user = sprintf("%.2f", $cache['num_inserts'] ? (($cache['num_inserts']) / ($time - $cache['start_time'])) : 0);
$apcversion = phpversion('apcu');
$phpversion = phpversion();
$number_vars = $cache['num_entries'];
$size_vars = bsize($cache['mem_size']);
$i = 0;
echo <<< EOB
<div class="info div1"><h2>General Cache Information</h2>
<table cellspacing=0><tbody>
<tr class=tr-0><td class=td-0>APCu Version</td><td>$apcversion</td></tr>
<tr class=tr-1><td class=td-0>PHP Version</td><td>$phpversion</td></tr>
EOB;
if (!empty($_SERVER['SERVER_NAME']))
echo "<tr class=tr-0><td class=td-0>APCu Host</td><td>{$_SERVER['SERVER_NAME']} $host</td></tr>\n";
if (!empty($_SERVER['SERVER_SOFTWARE']))
echo "<tr class=tr-1><td class=td-0>Server Software</td><td>{$_SERVER['SERVER_SOFTWARE']}</td></tr>\n";
echo <<<EOB
<tr class=tr-0><td class=td-0>Shared Memory</td><td>{$mem['num_seg']} Segment(s) with $seg_size
<br/> ({$cache['memory_type']} memory)
</td></tr>
EOB;
echo '<tr class=tr-1><td class=td-0>Start Time</td><td>', date(DATE_FORMAT, $cache['start_time']), '</td></tr>';
echo '<tr class=tr-0><td class=td-0>Uptime</td><td>', duration($cache['start_time']), '</td></tr>';
echo <<<EOB
</tbody></table>
</div>
<div class="info div1"><h2>Cache Information</h2>
<table cellspacing=0>
<tbody>
<tr class=tr-0><td class=td-0>Cached Variables</td><td>$number_vars ($size_vars)</td></tr>
<tr class=tr-1><td class=td-0>Hits</td><td>{$cache['num_hits']}</td></tr>
<tr class=tr-0><td class=td-0>Misses</td><td>{$cache['num_misses']}</td></tr>
<tr class=tr-1><td class=td-0>Request Rate (hits, misses)</td><td>$req_rate_user cache requests/second</td></tr>
<tr class=tr-0><td class=td-0>Hit Rate</td><td>$hit_rate_user cache requests/second</td></tr>
<tr class=tr-1><td class=td-0>Miss Rate</td><td>$miss_rate_user cache requests/second</td></tr>
<tr class=tr-0><td class=td-0>Insert Rate</td><td>$insert_rate_user cache requests/second</td></tr>
<tr class=tr-1><td class=td-0>Cache full count</td><td>{$cache['expunges']}</td></tr>
</tbody>
</table>
</div>
<div class="info div2"><h2>Runtime Settings</h2><table cellspacing=0><tbody>
EOB;
$j = 0;
foreach (ini_get_all('apcu') as $k => $v) {
echo "<tr class=tr-$j><td class=td-0>", $k, "</td><td>", str_replace(',', ',<br />', $v['local_value']), "</td></tr>\n";
$j = 1 - $j;
}
if ($mem['num_seg'] > 1 || $mem['num_seg'] == 1 && count($mem['block_lists'][0]) > 1)
$mem_note = "Memory Usage<br /><font size=-2>(multiple slices indicate fragments)</font>";
else
$mem_note = "Memory Usage";
echo <<< EOB
</tbody></table>
</div>
<div class="graph div3"><h2>Host Status Diagrams</h2>
<table cellspacing=0><tbody>
EOB;
$size = 'width=' . (GRAPH_SIZE + 50) . ' height=' . (GRAPH_SIZE + 10);
echo <<<EOB
<tr>
<td class=td-0>$mem_note</td>
<td class=td-1>Hits &amp; Misses</td>
</tr>
EOB;
echo
graphics_avail() ?
'<tr>' .
"<td class=td-0><img alt=\"\" $size src=\"$PHP_SELF&IMG=1&$time\"></td>" .
"<td class=td-1><img alt=\"\" $size src=\"$PHP_SELF&IMG=2&$time\"></td></tr>\n"
: "",
'<tr>',
'<td class=td-0><span class="green box">&nbsp;</span>Free: ', bsize($mem_avail) . sprintf(" (%.1f%%)", $mem_avail * 100 / $mem_size), "</td>\n",
'<td class=td-1><span class="green box">&nbsp;</span>Hits: ', $cache['num_hits'] . @sprintf(" (%.1f%%)", $cache['num_hits'] * 100 / ($cache['num_hits'] + $cache['num_misses'])), "</td>\n",
'</tr>',
'<tr>',
'<td class=td-0><span class="red box">&nbsp;</span>Used: ', bsize($mem_used) . sprintf(" (%.1f%%)", $mem_used * 100 / $mem_size), "</td>\n",
'<td class=td-1><span class="red box">&nbsp;</span>Misses: ', $cache['num_misses'] . @sprintf(" (%.1f%%)", $cache['num_misses'] * 100 / ($cache['num_hits'] + $cache['num_misses'])), "</td>\n";
echo <<< EOB
</tr>
</tbody></table>
<br/>
<h2>Detailed Memory Usage and Fragmentation</h2>
<table cellspacing=0><tbody>
<tr>
<td class=td-0 colspan=2><br/>
EOB;
// Fragementation: (freeseg - 1) / total_seg
$nseg = $freeseg = $fragsize = $freetotal = 0;
for ($i = 0; $i < $mem['num_seg']; $i++) {
$ptr = 0;
foreach ($mem['block_lists'][$i] as $block) {
if ($block['offset'] != $ptr) {
++$nseg;
}
$ptr = $block['offset'] + $block['size'];
/* Only consider blocks <5M for the fragmentation % */
if ($block['size'] < (5 * 1024 * 1024)) $fragsize += $block['size'];
$freetotal += $block['size'];
}
$freeseg += count($mem['block_lists'][$i]);
}
if ($freeseg > 1) {
$frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize / $freetotal) * 100, bsize($fragsize), bsize($freetotal), $freeseg);
} else {
$frag = "0%";
}
if (graphics_avail()) {
$size = 'width=' . (2 * GRAPH_SIZE + 150) . ' height=' . (GRAPH_SIZE + 10);
echo <<<EOB
<img alt="" $size src="$PHP_SELF&IMG=3&$time">
EOB;
}
echo <<<EOB
</br>Fragmentation: $frag
</td>
</tr>
EOB;
if (isset($mem['adist'])) {
foreach ($mem['adist'] as $i => $v) {
$cur = pow(2, $i);
$nxt = pow(2, $i + 1) - 1;
if ($i == 0) $range = "1";
else $range = "$cur - $nxt";
echo "<tr><th align=right>$range</th><td align=right>$v</td></tr>\n";
}
}
echo <<<EOB
</tbody></table>
</div>
EOB;
break;
// -----------------------------------------------
// User Cache Entries
// -----------------------------------------------
case OB_USER_CACHE:
if (!$AUTHENTICATED) {
echo '<div class="error">You need to login to see the user values here!<br/>&nbsp;<br/>';
put_login_link("Login now!");
echo '</div>';
break;
}
$fieldname = 'info';
$fieldheading = 'User Entry Label';
$fieldkey = 'info';
$cols = 6;
echo <<<EOB
<div class=sorting><form>Scope:
<input type=hidden name=ip value={$_GET['ip']}>
<input type=hidden name=type value={$_GET['type']}>
<input type=hidden name=OB value={$MYREQUEST['OB']}>
<select name=SCOPE>
EOB;
echo
"<option value=A", $MYREQUEST['SCOPE'] == 'A' ? " selected" : "", ">Active</option>",
"<option value=D", $MYREQUEST['SCOPE'] == 'D' ? " selected" : "", ">Deleted</option>",
"</select>",
", Sorting:<select name=SORT1>",
"<option value=H", $MYREQUEST['SORT1'] == 'H' ? " selected" : "", ">Hits</option>",
"<option value=Z", $MYREQUEST['SORT1'] == 'Z' ? " selected" : "", ">Size</option>",
"<option value=S", $MYREQUEST['SORT1'] == 'S' ? " selected" : "", ">$fieldheading</option>",
"<option value=A", $MYREQUEST['SORT1'] == 'A' ? " selected" : "", ">Last accessed</option>",
"<option value=M", $MYREQUEST['SORT1'] == 'M' ? " selected" : "", ">Last modified</option>",
"<option value=C", $MYREQUEST['SORT1'] == 'C' ? " selected" : "", ">Created at</option>",
"<option value=D", $MYREQUEST['SORT1'] == 'D' ? " selected" : "", ">Deleted at</option>";
if ($fieldname == 'info') echo
"<option value=D", $MYREQUEST['SORT1'] == 'T' ? " selected" : "", ">Timeout</option>";
echo
'</select>',
'<select name=SORT2>',
'<option value=D', $MYREQUEST['SORT2'] == 'D' ? ' selected' : '', '>DESC</option>',
'<option value=A', $MYREQUEST['SORT2'] == 'A' ? ' selected' : '', '>ASC</option>',
'</select>',
'<select name=COUNT onChange="form.submit()">',
'<option value=10 ', $MYREQUEST['COUNT'] == '10' ? ' selected' : '', '>Top 10</option>',
'<option value=20 ', $MYREQUEST['COUNT'] == '20' ? ' selected' : '', '>Top 20</option>',
'<option value=50 ', $MYREQUEST['COUNT'] == '50' ? ' selected' : '', '>Top 50</option>',
'<option value=100', $MYREQUEST['COUNT'] == '100' ? ' selected' : '', '>Top 100</option>',
'<option value=150', $MYREQUEST['COUNT'] == '150' ? ' selected' : '', '>Top 150</option>',
'<option value=200', $MYREQUEST['COUNT'] == '200' ? ' selected' : '', '>Top 200</option>',
'<option value=500', $MYREQUEST['COUNT'] == '500' ? ' selected' : '', '>Top 500</option>',
'<option value=0 ', $MYREQUEST['COUNT'] == '0' ? ' selected' : '', '>All</option>',
'</select>',
'&nbsp; Search: <input name=SEARCH value="', $MYREQUEST['SEARCH'], '" type=text size=25/>',
'&nbsp;<input type=submit value="GO!">',
'</form></div>';
if (isset($MYREQUEST['SEARCH'])) {
// Don't use preg_quote because we want the user to be able to specify a
// regular expression subpattern.
$MYREQUEST['SEARCH'] = '/' . str_replace('/', '\\/', $MYREQUEST['SEARCH']) . '/i';
if (preg_match($MYREQUEST['SEARCH'], 'test') === false) {
echo '<div class="error">Error: enter a valid regular expression as a search query.</div>';
break;
}
}
echo
'<div class="info"><table cellspacing=0><tbody>',
'<tr>',
'<th>', sortheader('S', $fieldheading, "&OB=" . $MYREQUEST['OB']), '</th>',
'<th>', sortheader('H', 'Hits', "&OB=" . $MYREQUEST['OB']), '</th>',
'<th>', sortheader('Z', 'Size', "&OB=" . $MYREQUEST['OB']), '</th>',
'<th>', sortheader('A', 'Last accessed', "&OB=" . $MYREQUEST['OB']), '</th>',
'<th>', sortheader('M', 'Last modified', "&OB=" . $MYREQUEST['OB']), '</th>',
'<th>', sortheader('C', 'Created at', "&OB=" . $MYREQUEST['OB']), '</th>';
if ($fieldname == 'info') {
$cols += 2;
echo '<th>', sortheader('T', 'Timeout', "&OB=" . $MYREQUEST['OB']), '</th>';
}
echo '<th>', sortheader('D', 'Deleted at', "&OB=" . $MYREQUEST['OB']), '</th></tr>';
// builds list with alpha numeric sortable keys
//
$list = array();
foreach ($cache[$scope_list[$MYREQUEST['SCOPE']]] as $i => $entry) {
switch ($MYREQUEST['SORT1']) {
case 'A':
$k = sprintf('%015d-', $entry['access_time']);
break;
case 'H':
$k = sprintf('%015d-', $entry['num_hits']);
break;
case 'Z':
$k = sprintf('%015d-', $entry['mem_size']);
break;
case 'M':
$k = sprintf('%015d-', $entry['mtime']);
break;
case 'C':
$k = sprintf('%015d-', $entry['creation_time']);
break;
case 'T':
$k = sprintf('%015d-', $entry['ttl']);
break;
case 'D':
$k = sprintf('%015d-', $entry['deletion_time']);
break;
case 'S':
$k = $entry["info"];
break;
}
if (!$AUTHENTICATED) {
// hide all path entries if not logged in
$list[$k . $entry[$fieldname]] = preg_replace('/^.*(\\/|\\\\)/', '*hidden*/', $entry);
} else {
$list[$k . $entry[$fieldname]] = $entry;
}
}
if ($list) {
// sort list
//
switch ($MYREQUEST['SORT2']) {
case "A":
krsort($list);
break;
case "D":
ksort($list);
break;
}
// output list
$i = 0;
foreach ($list as $k => $entry) {
if (!$MYREQUEST['SEARCH'] || preg_match($MYREQUEST['SEARCH'], $entry[$fieldname]) != 0) {
$sh = md5($entry["info"]);
$field_value = htmlentities(strip_tags($entry[$fieldname], ''), ENT_QUOTES, 'UTF-8');
echo
'<tr id="key-' . $sh . '" class=tr-', $i % 2, '>',
"<td class=td-0><a href=\"$MY_SELF&OB=", $MYREQUEST['OB'], "&SH=", $sh, "#key-" . $sh . "\">", $field_value, '</a></td>',
'<td class="td-n center">', $entry['num_hits'], '</td>',
'<td class="td-n right">', $entry['mem_size'], '</td>',
'<td class="td-n center">', date(DATE_FORMAT, $entry['access_time']), '</td>',
'<td class="td-n center">', date(DATE_FORMAT, $entry['mtime']), '</td>',
'<td class="td-n center">', date(DATE_FORMAT, $entry['creation_time']), '</td>';
if ($fieldname == 'info') {
if ($entry['ttl'])
echo '<td class="td-n center">' . $entry['ttl'] . ' seconds</td>';
else
echo '<td class="td-n center">None</td>';
}
if ($entry['deletion_time']) {
echo '<td class="td-last center">', date(DATE_FORMAT, $entry['deletion_time']), '</td>';
} else if ($MYREQUEST['OB'] == OB_USER_CACHE) {
echo '<td class="td-last center">';
echo '[<a href="', $MY_SELF, '&OB=', $MYREQUEST['OB'], '&DU=', urlencode($entry[$fieldkey]), '">Delete Now</a>]';
echo '</td>';
} else {
echo '<td class="td-last center"> &nbsp; </td>';
}
echo '</tr>';
if ($sh == $MYREQUEST["SH"]) {
echo '<tr>';
echo '<td colspan="7"><pre>' . htmlentities(print_r(apcu_fetch($entry['info']), 1)) . '</pre></td>';
echo '</tr>';
}
$i++;
if ($i == $MYREQUEST['COUNT'])
break;
}
}
} else {
echo '<tr class=tr-0><td class="center" colspan=', $cols, '><i>No data</i></td></tr>';
}
echo <<< EOB
</tbody></table>
EOB;
if ($list && $i < count($list)) {
echo "<a href=\"$MY_SELF&OB=", $MYREQUEST['OB'], "&COUNT=0\"><i>", count($list) - $i, ' more available...</i></a>';
}
echo <<< EOB
</div>
EOB;
break;
// -----------------------------------------------
// Version check
// -----------------------------------------------
case OB_VERSION_CHECK:
echo <<<EOB
<div class="info"><h2>APCu Version Information</h2>
<table cellspacing=0><tbody>
<tr>
<th></th>
</tr>
EOB;
if (defined('PROXY')) {
$ctxt = stream_context_create(array('http' => array('proxy' => PROXY, 'request_fulluri' => True)));
$rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apcu.rss", False, $ctxt);
} else {
$rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apcu.rss");
}
if (!$rss) {
echo '<tr class="td-last center"><td>Unable to fetch version information.</td></tr>';
} else {
$apcversion = phpversion('apcu');
preg_match('!<title>APCu ([0-9.]+)</title>!', $rss, $match);
echo '<tr class="tr-0 center"><td>';
if (version_compare($apcversion, $match[1], '>=')) {
echo '<div class="ok">You are running the latest version of APCu (' . $apcversion . ')</div>';
$i = 3;
} else {
echo '<div class="failed">You are running an older version of APCu (' . $apcversion . '),
newer version ' . $match[1] . ' is available at <a href="http://pecl.php.net/package/APCu/' . $match[1] . '">
http://pecl.php.net/package/APCu/' . $match[1] . '</a>
</div>';
$i = -1;
}
echo '</td></tr>';
echo '<tr class="tr-0"><td><h3>Change Log:</h3><br/>';
preg_match_all('!<(title|description)>([^<]+)</\\1>!', $rss, $match);
$changelog = $match[2];
for ($j = 2; $j + 1 < count($changelog); $j += 2) {
$v = $changelog[$j];
if ($i < 0 && version_compare($apcversion, $ver, '>=')) {
break;
} else if (!$i--) {
break;
}
list($unused, $ver) = $v;
$changes = $changelog[$j + 1];
echo "<b><a href=\"http://pecl.php.net/package/APCu/$ver\">" . htmlspecialchars($v, ENT_QUOTES, 'UTF-8') . "</a></b><br><blockquote>";
echo nl2br(htmlspecialchars($changes, ENT_QUOTES, 'UTF-8')) . "</blockquote>";
}
echo '</td></tr>';
}
echo <<< EOB
</tbody></table>
</div>
EOB;
break;
}
echo <<< EOB
</div>
EOB;
?>
<!-- <?php echo "\nBased on APCGUI By R.Becker\n$VERSION\n" ?> -->
</body>
</html>
[api.go2yd.com]
prefix = /home/services/api.go2yd.com
user = nobody
group = nobody
listen = 0.0.0.0:9000
;listen = /var/run/php-fpm/api.go2yd.com.sock
listen.backlog = 2048
listen.owner = nobody
listen.group = nobody
listen.mode = 0600
pm = static
pm.max_children = 256
pm.max_requests = 100
pm.status_path = /status-fpm
access.log = /home/services/api.go2yd.com/logs/access.log
access.format = "%R - %u %t \"%m %r%Q%q\" %s %{mili}d %{kilo}M %C%%"
slowlog = /home/services/api.go2yd.com/logs/fpm-slow.log
request_slowlog_timeout = 1s
request_terminate_timeout = 6s
catch_workers_output = yes
env[PATH] = /usr/local/bin:/usr/bin:/bin
<?php
$config = array(
'debug' => false,
'mode' => 'development',
'extension' => 'tideways_xhprof',
'save.handler' => 'mongodb',
'db.host' => 'mongodb://10.126.150.23:27017',
'db.db' => 'xhprof',
'db.options' => array(),
'date.format' => 'Y-m-d H:i:s',
'detail.count' => 6,
'page.limit' => 25,
// Profile 1 in 100 requests.
// You can return true to profile every request.
'profiler.enable' => function () {
// 暂时关闭xhgui性能监控
// if (strpos($_SERVER['SCRIPT_NAME'], 'Action.php') !== false)
// {
// return true;
// }
return false;
},
'profiler.simple_url' => function ($url) {
return preg_replace('/\=\d+/', '', $url);
},
//'/home/admin/www/xhgui/webroot','F:/phpPro'
'profiler.filter_path' => array()
);
if (!extension_loaded('tideways_xhprof'))
{
error_log('xhgui - extension tideways_xhprof must be loaded');
return;
}
if ($config['debug'])
{
ini_set('display_errors', 1); // 该选项设置是否将错误信息作为输出的一部分显示到屏幕,或者对用户隐藏而不显示。
}
// 指定监控的目录
if (is_array($config['profiler.filter_path']) && in_array($_SERVER['DOCUMENT_ROOT'], $config['profiler.filter_path']))
{
return;
}
if ((!extension_loaded('mongo') && !extension_loaded('mongodb')) && $config['save.handler'] === 'mongodb')
{
error_log('xhgui - extension mongo not loaded');
return;
}
if (!shouldRun())
{
return;
}
if (!isset($_SERVER['REQUEST_TIME_FLOAT']))
{
$_SERVER['REQUEST_TIME_FLOAT'] = microtime(true);
}
if ($config['extension'] == 'tideways_xhprof' && extension_loaded('tideways_xhprof'))
{
tideways_xhprof_enable(TIDEWAYS_XHPROF_FLAGS_MEMORY | TIDEWAYS_XHPROF_FLAGS_MEMORY_MU | TIDEWAYS_XHPROF_FLAGS_MEMORY_PMU | TIDEWAYS_XHPROF_FLAGS_CPU);
}
else
{
error_log("Please check the extension name in config.php, you can use the 'php -m' command.");
return;
}
//注册一个会在php中止时执行的函数
register_shutdown_function(
function () {
$data['profile'] = tideways_xhprof_disable();
// ignore_user_abort(true) allows your PHP script to continue executing, even if the user has terminated their request.
// Further Reading: http://blog.preinheimer.com/index.php?/archives/248-When-does-a-user-abort.html
// flush() asks PHP to send any data remaining in the output buffers. This is normally done when the script completes, but
// since we're delaying that a bit by dealing with the xhprof stuff, we'll do it now to avoid making the user wait.
ignore_user_abort(true);
flush();
$uri = array_key_exists('REQUEST_URI', $_SERVER) ? $_SERVER['REQUEST_URI'] : null;
if (empty($uri) && isset($_SERVER['argv']))
{
$cmd = basename($_SERVER['argv'][0]);
$uri = $cmd . ' ' . implode(' ', array_slice($_SERVER['argv'], 1));
}
$time = array_key_exists('REQUEST_TIME', $_SERVER) ? $_SERVER['REQUEST_TIME'] : time();
$requestTimeFloat = explode('.', $_SERVER['REQUEST_TIME_FLOAT']);
if (!isset($requestTimeFloat[1]))
{
$requestTimeFloat[1] = 0;
}
$requestTs = new MongoDB\BSON\UTCDateTime($time * 1000);
$requestTsMicro = new MongoDB\BSON\UTCDateTime($_SERVER['REQUEST_TIME_FLOAT'] * 1000);
$data['meta'] = array(
'url' => $uri,
'SERVER' => $_SERVER,
'get' => $_GET,
'env' => $_ENV,
'simple_url' => simpleUrl($uri),
'request_ts' => $requestTs,
'request_ts_micro' => $requestTsMicro,
'request_date' => date('Y-m-d', $time),
);
// 保存数据到MongoDB
save2mongo($data);
}
);
function simpleUrl($url)
{
global $config;
$callable = $config['profiler.simple_url'];
if (is_callable($callable))
{
return call_user_func($callable, $url);
}
return preg_replace('/\=\d+/', '', $url);
}
function shouldRun()
{
global $config;
$callback = $config['profiler.enable'];
if (!is_callable($callback))
{
return false;
}
return (bool)$callback();
}
function save2mongo($data)
{
global $config;
$manager = new MongoDB\Driver\Manager($config['db.host']);
$bulk = new MongoDB\Driver\BulkWrite();
try
{
$bulk->insert($data);
$writeConcern = new MongoDB\Driver\WriteConcern(1, 100);
$manager->executeBulkWrite($config['db.db'] . '.results', $bulk, $writeConcern);
} catch (Exception $e)
{
error_log('xhgui - ' . $e->getMessage());
}
}
#!/usr/bin/env bash
working_dir=`dirname $0`
echo "working_dir :"$working_dir
CGI_CLIENT="${working_dir}/cgi-fcgi"
function log()
{
echo "[`date +%Y-%m-%d %H:%M:%S`] $@"
}
export LD_LIBRARY_PATH=${working_dir}
if [ ! -x "${CGI_CLIENT}" ]
then
log "cgi client not found or not executable"
exit 1
fi
function fcgi_get()
{
document_root=$1
script_file=$2
host=$3
port=$4
server_name=$5
REQUEST_URI=${script} \
SERVER_ADDR=$3 \
REQUEST_METHOD=GET \
SERVER_NAME=${server_name} \
DOCUMENT_ROOT=${document_root} \
DOCUMENT_URI=${script} \
SCRIPT_NAME=${script} \
SCRIPT_FILENAME=${document_root}${script} \
QUERY_STRING= \
REMOTE_ADDR=127.0.0.1 \
GATEWAY_INTERFACE=CGI/1.1 \
${CGI_CLIENT} -bind -connect ${host}:${port}
}
function api_get()
{
script=$1
port=$2
domain_prefix=$3
fcgi_get "/home/services/api.go2yd.com/htdocs/Website/public" ${script} 127.0.0.1 ${port} {$domain_prefix}".go2yd.com"
}
result=`api_get "/test.php" $1 $2 | awk -F"\r" '{print $NF}'`
check=`echo ${result} | grep "success"`
if [ "" = "${check}" ]
then
echo ${result}
exit 1
else
echo "success"
fi
#!/usr/bin/env bash
working_dir=`dirname $0`
CGI_CLIENT="${working_dir}/cgi-fcgi"
export LD_LIBRARY_PATH=${working_dir}
function fcgi_get()
{
document_root=$1
script_file=$2
host=$3
port=$4
server_name=$5
REQUEST_METHOD=GET \
SERVER_NAME=${server_name} \
DOCUMENT_ROOT=${document_root} \
DOCUMENT_URI=${script} \
SCRIPT_NAME=${script} \
SCRIPT_FILENAME=${document_root}${script} \
QUERY_STRING= \
GATEWAY_INTERFACE=CGI/1.1 \
REMOTE_ADDR = 127.0.0.1 \
REQUEST_URI=${script}
${CGI_CLIENT} -bind -connect ${host}:${port}
}
function api_get()
{
script=$1
fcgi_get "/home/services/api.go2yd.com/htdocs/Website" ${script} 127.0.0.1 9000 "qa-int.go2yd.com/Website"
}
while [ "`ps -ax | grep php-fpm -c`" = 0 ]; do
sleep 5;
done
sleep 10
for file in `find /home/services/api.go2yd.com/htdocs/Website/ | grep -oP '(?<=/home/services/api.go2yd.com/htdocs/Website).*\.php$'`; do
api_get $file
done
<?php
if ($_GET['clear'] == "true")
{
apcu_delete("coverage");
print("done!");
exit();
} else {
print("need param 'clear' be 'true'");
}
<?php
$coverage = apcu_fetch("coverage");
if ($coverage == false)
{
$coverage = array();
}
$timestamp = time();
$xml = new XMLWriter();
$xml->openMemory();
$xml->startDocument('1.0','UTF-8');
$xml->setIndent(4);
$xml->startElement('coverage');
$xml->writeAttribute('generated', $timestamp);
$xml->startElement('project');
$xml->writeAttribute('timestamp', $timestamp);
$sum_ncloc = 0;
$sum_methods = 0;
$sum_coveredmethods = 0;
$sum_statements = 0;
$sum_coveredstatements = 0;
$sum_elements = 0;
$sum_coveredelements = 0;
function generate_line_element($line_coverage, $line_number, $xml)
{
# $xml->startElement('line');
# $xml->writeAttribute('num', $line_number);
# $xml->writeAttribute('type', 'stmt');
# $xml->writeAttribute('value', $line_coverage);
# $xml->endElement();
$GLOBALS['loc']++;
if ($line_coverage > -2) {
$GLOBALS['ncloc']++;
}
$GLOBALS['statements']++;
if ($line_coverage >= 1) {
$GLOBALS['coveredstatements']++;
}
}
function gerenate_file_element($file_coverage, $filename, $xml)
{
$xml->startElement('file');
$xml->writeAttribute('name', $filename);
# $content = file_get_contents($filename);
# try {
# $parser = new PHPFuncParser($content);
# $function_list = $parser -> process();
# $GLOBALS['function_list'] = $function_list;
# } catch (RuntimeException $e) {
# var_dump($e->getMessage());
# exit(1);
# }
$GLOBALS['loc'] = 0;
$GLOBALS['ncloc'] = 0;
$GLOBALS['methods'] = 0;
$GLOBALS['coveredmethods'] = 0;
$GLOBALS['statements'] = 0;
$GLOBALS['coveredstatements'] = 0;
$GLOBALS['elements'] = 0;
$GLOBALS['coveredelements'] = 0;
array_walk($file_coverage, 'generate_line_element', $xml);
$GLOBALS['elements'] = $GLOBALS['methods'] + $GLOBALS['statements'];
$GLOBALS['coveredelements'] = $GLOBALS['coveredmethods'] + $GLOBALS['coveredstatements'];
$xml->startElement('metrics');
$xml->writeAttribute('loc', $GLOBALS['loc']);
$xml->writeAttribute('ncloc', $GLOBALS['ncloc']);
$xml->writeAttribute('methods', $GLOBALS['methods']);
$xml->writeAttribute('coveredmethods', $GLOBALS['coveredmethods']);
$xml->writeAttribute('statements', $GLOBALS['statements']);
$xml->writeAttribute('coveredstatements', $GLOBALS['coveredstatements']);
$xml->writeAttribute('elements', $GLOBALS['elements']);
$xml->writeAttribute('coveredelements', $GLOBALS['coveredelements']);
$GLOBALS['sum_loc'] += $GLOBALS['loc'];
$GLOBALS['sum_ncloc'] += $GLOBALS['ncloc'];
$GLOBALS['sum_methods'] += $GLOBALS['methods'];
$GLOBALS['sum_coveredmethods'] += $GLOBALS['coveredmethods'];
$GLOBALS['sum_statements'] += $GLOBALS['statements'];
$GLOBALS['sum_coveredstatements'] += $GLOBALS['coveredstatements'];
$GLOBALS['sum_elements'] += $GLOBALS['elements'];
$GLOBALS['sum_coveredelements'] += $GLOBALS['coveredelements'];
$xml->endElement();
$xml->endElement();
}
array_walk($coverage, 'gerenate_file_element', $xml);
$xml->startElement('metrics');
$xml->writeAttribute('loc', $GLOBALS['sum_loc']);
$xml->writeAttribute('ncloc', $GLOBALS['sum_ncloc']);
$xml->writeAttribute('methods', $GLOBALS['sum_methods']);
$xml->writeAttribute('coveredmethods', $GLOBALS['sum_coveredmethods']);
$xml->writeAttribute('statements', $GLOBALS['sum_statements']);
$xml->writeAttribute('coveredstatements', $GLOBALS['sum_coveredstatements']);
$xml->writeAttribute('elements', $GLOBALS['sum_elements']);
$xml->writeAttribute('coveredelements', $GLOBALS['sum_coveredelements']);
$xml->endElement();
$xml->endElement();
$xml->endElement();
$xml->endDocument();
#$xml->flush();
header("Content-type: text/xml");
print_r($coverage);
<?php
$coverage = apcu_fetch("coverage");
if ($coverage == false)
{
$coverage = array();
}
$timestamp = time();
$xml = new XMLWriter();
$xml->openMemory();
$xml->startDocument('1.0','UTF-8');
$xml->setIndent(4);
$xml->startElement('coverage');
$xml->writeAttribute('generated', $timestamp);
$xml->startElement('project');
$xml->writeAttribute('timestamp', $timestamp);
$sum_ncloc = 0;
$sum_methods = 0;
$sum_coveredmethods = 0;
$sum_statements = 0;
$sum_coveredstatements = 0;
$sum_elements = 0;
$sum_coveredelements = 0;
function generate_line_element($line_coverage, $line_number, $xml)
{
# $xml->startElement('line');
# $xml->writeAttribute('num', $line_number);
# $xml->writeAttribute('type', 'stmt');
# $xml->writeAttribute('value', $line_coverage);
# $xml->endElement();
$GLOBALS['loc']++;
if ($line_coverage > -2) {
$GLOBALS['ncloc']++;
}
$GLOBALS['statements']++;
if ($line_coverage >= 1) {
$GLOBALS['coveredstatements']++;
}
}
function gerenate_file_element($file_coverage, $filename, $xml)
{
$xml->startElement('file');
$xml->writeAttribute('name', $filename);
# $content = file_get_contents($filename);
# try {
# $parser = new PHPFuncParser($content);
# $function_list = $parser -> process();
# $GLOBALS['function_list'] = $function_list;
# } catch (RuntimeException $e) {
# var_dump($e->getMessage());
# exit(1);
# }
$GLOBALS['loc'] = 0;
$GLOBALS['ncloc'] = 0;
$GLOBALS['methods'] = 0;
$GLOBALS['coveredmethods'] = 0;
$GLOBALS['statements'] = 0;
$GLOBALS['coveredstatements'] = 0;
$GLOBALS['elements'] = 0;
$GLOBALS['coveredelements'] = 0;
array_walk($file_coverage, 'generate_line_element', $xml);
$GLOBALS['elements'] = $GLOBALS['methods'] + $GLOBALS['statements'];
$GLOBALS['coveredelements'] = $GLOBALS['coveredmethods'] + $GLOBALS['coveredstatements'];
$xml->startElement('metrics');
$xml->writeAttribute('loc', $GLOBALS['loc']);
$xml->writeAttribute('ncloc', $GLOBALS['ncloc']);
$xml->writeAttribute('methods', $GLOBALS['methods']);
$xml->writeAttribute('coveredmethods', $GLOBALS['coveredmethods']);
$xml->writeAttribute('statements', $GLOBALS['statements']);
$xml->writeAttribute('coveredstatements', $GLOBALS['coveredstatements']);
$xml->writeAttribute('elements', $GLOBALS['elements']);
$xml->writeAttribute('coveredelements', $GLOBALS['coveredelements']);
$GLOBALS['sum_loc'] += $GLOBALS['loc'];
$GLOBALS['sum_ncloc'] += $GLOBALS['ncloc'];
$GLOBALS['sum_methods'] += $GLOBALS['methods'];
$GLOBALS['sum_coveredmethods'] += $GLOBALS['coveredmethods'];
$GLOBALS['sum_statements'] += $GLOBALS['statements'];
$GLOBALS['sum_coveredstatements'] += $GLOBALS['coveredstatements'];
$GLOBALS['sum_elements'] += $GLOBALS['elements'];
$GLOBALS['sum_coveredelements'] += $GLOBALS['coveredelements'];
$xml->endElement();
$xml->endElement();
}
array_walk($coverage, 'gerenate_file_element', $xml);
$xml->startElement('metrics');
$xml->writeAttribute('loc', $GLOBALS['sum_loc']);
$xml->writeAttribute('ncloc', $GLOBALS['sum_ncloc']);
$xml->writeAttribute('methods', $GLOBALS['sum_methods']);
$xml->writeAttribute('coveredmethods', $GLOBALS['sum_coveredmethods']);
$xml->writeAttribute('statements', $GLOBALS['sum_statements']);
$xml->writeAttribute('coveredstatements', $GLOBALS['sum_coveredstatements']);
$xml->writeAttribute('elements', $GLOBALS['sum_elements']);
$xml->writeAttribute('coveredelements', $GLOBALS['sum_coveredelements']);
$xml->endElement();
$xml->endElement();
$xml->endElement();
$xml->endDocument();
#$xml->flush();
header("Content-type: text/xml");
print($xml->outputMemory());
<?php
$coverage = apcu_fetch("coverage");
echo json_encode($coverage);
<?php
var_dump(apcu_cache_info(true));
var_dump(apcu_sma_info());
var_dump(memory_get_usage());
<?php
xdebug_start_code_coverage(1|2);
$GLOBALS["stored_coverage"] = array();
function my_print($msg)
{
#print($msg);
}
function my_print_r($var)
{
#print_r($var);
}
function merge_line_coverage($new_line_coverage, $key)
{
$old_line_coverage = &$GLOBALS["stored_file_coverage"];
if (array_key_exists($key, $old_line_coverage))
{
if ($old_line_coverage[$key] < $new_line_coverage)
{
$old_line_coverage[$key] = $new_line_coverage;
}
} else {
$old_line_coverage[$key] = $new_line_coverage;
}
}
function merge_file_coverage($new_file_coverage, $key)
{
$stored_coverage = &$GLOBALS["stored_coverage"];
if (array_key_exists($key, $stored_coverage))
{
$GLOBALS["stored_file_coverage"] = &$stored_coverage[$key];
array_walk($new_file_coverage, 'merge_line_coverage');
} else {
$stored_coverage[$key] = $new_file_coverage;
}
}
function shutdown ()
{
$previews_coverage = array();
apcu_add("coverage", $previews_coverage);
$previews_coverage = apcu_fetch("coverage");
# $previews_coverage = apcu_fetch("coverage");
# if ($previews_coverage == false)
# {
# my_print("\$previews_coverage = false\n");
# $previews_coverage = array();
# }
my_print("\n\npreviews_coverage:\n");
my_print_r($previews_coverage);
my_print("\n");
$GLOBALS["stored_coverage"] = $previews_coverage;
$coverage = xdebug_get_code_coverage();
my_print("\n\ncoverage:\n");
my_print_r($coverage);
my_print("\n");
array_walk($coverage, 'merge_file_coverage');
my_print("\n\nmerged_coverage:\n");
my_print_r($GLOBALS["stored_coverage"]);
my_print("\n");
# apcu_delete("coverage");
apcu_store("coverage", $GLOBALS["stored_coverage"]);
xdebug_stop_code_coverage();
}
register_shutdown_function('shutdown');
#!/usr/bin/env bash
dir=`dirname $0`
cp -r ${dir}/coverage /home/services/api.go2yd.com/
cp -r ${dir}/collect_coverage /home/services/api.go2yd.com/htdocs/Website/
echo "zend_extension=/usr/lib64/php/modules/xdebug.so" >> /etc/php.ini
echo "auto_prepend_file=/home/services/api.go2yd.com/coverage/StartRecordCoverage.php" >> /etc/php.ini
sed -i 's/php_admin_value\[memory_limit\].*$/php_admin_value[memory_limit] = 1024M/g' /etc/php-fpm.d/api.go2yd.com.conf
nohup sh ${dir}/call_all.sh &
#日志分割
59 23 * * * /usr/sbin/logrotate -f /etc/logrotate.conf
#ipip 更新数据字典
0 3 * * * /bin/bash /home/services/ipip/ipip.sh > /home/services/api.go2yd.com/logs/ipip.log
###################### Filebeat Configuration #########################
filebeat.inputs:
- type: log
paths:
- /home/services/api.go2yd.com/logs/fpm-error.log
fields:
log_type: 'fpm-error_log'
service_name: 'api.go2yd.com'
fields_under_root: false
- type: log
paths:
- /home/services/api.go2yd.com/logs/fpm-slow.log
multiline.pattern: '^$'
multiline.negate: true
multiline.match: after
fields:
log_type: 'fpm-slowlog'
service_name: 'api.go2yd.com'
fields_under_root: false
- type: log
paths:
- /home/services/api.go2yd.com/logs/php-error.log
multiline.pattern: '^\[\d{2}-'
multiline.negate: true
multiline.match: after
fields:
log_type: 'php-error_log'
service_name: 'api.go2yd.com'
fields_under_root: false
#- type: log
#
# paths:
# - /home/services/api.go2yd.com/logs/access.log
#
# fields:
# log_type: 'fpm-access_log'
# service_name: 'a1.go2yd.com'
# fields_under_root: false
#output.logstash:
#hosts: ["log.transfer.v.yidian-inc.com:5044"]
#hosts: ["10.126.154.124:5044"]
#hosts: ["172.29.60.5:5044"]
output.kafka:
enable: true
hosts: ["10.103.17.40:8091", "10.103.17.41:8091", "10.103.17.42:8091", "10.103.17.43:8091", "10.103.32.28:8091", "10.103.32.29:8091", "10.120.187.37:8091", "10.120.187.38:8091", "10.120.187.39:8091"]
topic: "%{[fields.log_type]}"
codec.format:
string: "%{[fields.service_name]}|${HOSTNAME} %{[message]}"
logging.level: warning
logging.to_files: true
logging.files:
path: /home/services/api.go2yd.com/logs
name: filebeat.log
rotateeverybytes: 52428800
keepfiles: 7
[PHP]
;;;;;;;;;;;;;;;;;;;
; About php.ini ;
;;;;;;;;;;;;;;;;;;;
; PHP's initialization file, generally called php.ini, is responsible for
; configuring many of the aspects of PHP's behavior.
; PHP attempts to find and load this configuration from a number of locations.
; The following is a summary of its search order:
; 1. SAPI module specific location.
; 2. The PHPRC environment variable. (As of PHP 5.2.0)
; 3. A number of predefined registry keys on Windows (As of PHP 5.2.0)
; 4. Current working directory (except CLI)
; 5. The web server's directory (for SAPI modules), or directory of PHP
; (otherwise in Windows)
; 6. The directory from the --with-config-file-path compile time option, or the
; Windows directory (C:\windows or C:\winnt)
; See the PHP docs for more specific information.
; http://php.net/configuration.file
; The syntax of the file is extremely simple. Whitespace and lines
; beginning with a semicolon are silently ignored (as you probably guessed).
; Section headers (e.g. [Foo]) are also silently ignored, even though
; they might mean something in the future.
; Directives following the section heading [PATH=/www/mysite] only
; apply to PHP files in the /www/mysite directory. Directives
; following the section heading [HOST=www.example.com] only apply to
; PHP files served from www.example.com. Directives set in these
; special sections cannot be overridden by user-defined INI files or
; at runtime. Currently, [PATH=] and [HOST=] sections only work under
; CGI/FastCGI.
; http://php.net/ini.sections
; Directives are specified using the following syntax:
; directive = value
; Directive names are *case sensitive* - foo=bar is different from FOO=bar.
; Directives are variables used to configure PHP or PHP extensions.
; There is no name validation. If PHP can't find an expected
; directive because it is not set or is mistyped, a default value will be used.
; The value can be a string, a number, a PHP constant (e.g. E_ALL or M_PI), one
; of the INI constants (On, Off, True, False, Yes, No and None) or an expression
; (e.g. E_ALL & ~E_NOTICE), a quoted string ("bar"), or a reference to a
; previously set variable or directive (e.g. ${foo})
; Expressions in the INI file are limited to bitwise operators and parentheses:
; | bitwise OR
; ^ bitwise XOR
; & bitwise AND
; ~ bitwise NOT
; ! boolean NOT
; Boolean flags can be turned on using the values 1, On, True or Yes.
; They can be turned off using the values 0, Off, False or No.
; An empty string can be denoted by simply not writing anything after the equal
; sign, or by using the None keyword:
; foo = ; sets foo to an empty string
; foo = None ; sets foo to an empty string
; foo = "None" ; sets foo to the string 'None'
; If you use constants in your value, and these constants belong to a
; dynamically loaded extension (either a PHP extension or a Zend extension),
; you may only use these constants *after* the line that loads the extension.
;;;;;;;;;;;;;;;;;;;
; About this file ;
;;;;;;;;;;;;;;;;;;;
; PHP comes packaged with two INI files. One that is recommended to be used
; in production environments and one that is recommended to be used in
; development environments.
; php.ini-production contains settings which hold security, performance and
; best practices at its core. But please be aware, these settings may break
; compatibility with older or less security conscience applications. We
; recommending using the production ini in production and testing environments.
; php.ini-development is very similar to its production variant, except it is
; much more verbose when it comes to errors. We recommend using the
; development version only in development environments, as errors shown to
; application users can inadvertently leak otherwise secure information.
; This is php.ini-production INI file.
;;;;;;;;;;;;;;;;;;;
; Quick Reference ;
;;;;;;;;;;;;;;;;;;;
; The following are all the settings which are different in either the production
; or development versions of the INIs with respect to PHP's default behavior.
; Please see the actual settings later in the document for more details as to why
; we recommend these changes in PHP's behavior.
; display_errors
; Default Value: On
; Development Value: On
; Production Value: Off
; display_startup_errors
; Default Value: Off
; Development Value: On
; Production Value: Off
; error_reporting
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; html_errors
; Default Value: On
; Development Value: On
; Production value: On
; log_errors
; Default Value: Off
; Development Value: On
; Production Value: On
; max_input_time
; Default Value: -1 (Unlimited)
; Development Value: 60 (60 seconds)
; Production Value: 60 (60 seconds)
; output_buffering
; Default Value: Off
; Development Value: 4096
; Production Value: 4096
; register_argc_argv
; Default Value: On
; Development Value: Off
; Production Value: Off
; request_order
; Default Value: None
; Development Value: "GP"
; Production Value: "GP"
; session.gc_divisor
; Default Value: 100
; Development Value: 1000
; Production Value: 1000
; session.hash_bits_per_character
; Default Value: 4
; Development Value: 5
; Production Value: 5
; short_open_tag
; Default Value: On
; Development Value: Off
; Production Value: Off
; track_errors
; Default Value: Off
; Development Value: On
; Production Value: Off
; url_rewriter.tags
; Default Value: "a=href,area=href,frame=src,form=,fieldset="
; Development Value: "a=href,area=href,frame=src,input=src,form=fakeentry"
; Production Value: "a=href,area=href,frame=src,input=src,form=fakeentry"
; variables_order
; Default Value: "EGPCS"
; Development Value: "GPCS"
; Production Value: "GPCS"
;;;;;;;;;;;;;;;;;;;;
; php.ini Options ;
;;;;;;;;;;;;;;;;;;;;
; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini"
;user_ini.filename = ".user.ini"
; To disable this feature set this option to empty value
;user_ini.filename =
; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes)
;user_ini.cache_ttl = 300
;;;;;;;;;;;;;;;;;;;;
; Language Options ;
;;;;;;;;;;;;;;;;;;;;
; Enable the PHP scripting language engine under Apache.
; http://php.net/engine
engine = On
; This directive determines whether or not PHP will recognize code between
; <? and ?> tags as PHP source which should be processed as such. It is
; generally recommended that <?php and ?> should be used and that this feature
; should be disabled, as enabling it may result in issues when generating XML
; documents, however this remains supported for backward compatibility reasons.
; Note that this directive does not control the <?= shorthand tag, which can be
; used regardless of this directive.
; Default Value: On
; Development Value: Off
; Production Value: Off
; http://php.net/short-open-tag
short_open_tag = Off
; The number of significant digits displayed in floating point numbers.
; http://php.net/precision
precision = 14
; Output buffering is a mechanism for controlling how much output data
; (excluding headers and cookies) PHP should keep internally before pushing that
; data to the client. If your application's output exceeds this setting, PHP
; will send that data in chunks of roughly the size you specify.
; Turning on this setting and managing its maximum buffer size can yield some
; interesting side-effects depending on your application and web server.
; You may be able to send headers and cookies after you've already sent output
; through print or echo. You also may see performance benefits if your server is
; emitting less packets due to buffered output versus PHP streaming the output
; as it gets it. On production servers, 4096 bytes is a good setting for performance
; reasons.
; Note: Output buffering can also be controlled via Output Buffering Control
; functions.
; Possible Values:
; On = Enabled and buffer is unlimited. (Use with caution)
; Off = Disabled
; Integer = Enables the buffer and sets its maximum size in bytes.
; Note: This directive is hardcoded to Off for the CLI SAPI
; Default Value: Off
; Development Value: 4096
; Production Value: 4096
; http://php.net/output-buffering
output_buffering = 4096
; You can redirect all of the output of your scripts to a function. For
; example, if you set output_handler to "mb_output_handler", character
; encoding will be transparently converted to the specified encoding.
; Setting any output handler automatically turns on output buffering.
; Note: People who wrote portable scripts should not depend on this ini
; directive. Instead, explicitly set the output handler using ob_start().
; Using this ini directive may cause problems unless you know what script
; is doing.
; Note: You cannot use both "mb_output_handler" with "ob_iconv_handler"
; and you cannot use both "ob_gzhandler" and "zlib.output_compression".
; Note: output_handler must be empty if this is set 'On' !!!!
; Instead you must use zlib.output_handler.
; http://php.net/output-handler
;output_handler =
; Transparent output compression using the zlib library
; Valid values for this option are 'off', 'on', or a specific buffer size
; to be used for compression (default is 4KB)
; Note: Resulting chunk size may vary due to nature of compression. PHP
; outputs chunks that are few hundreds bytes each as a result of
; compression. If you prefer a larger chunk size for better
; performance, enable output_buffering in addition.
; Note: You need to use zlib.output_handler instead of the standard
; output_handler, or otherwise the output will be corrupted.
; http://php.net/zlib.output-compression
zlib.output_compression = Off
; http://php.net/zlib.output-compression-level
;zlib.output_compression_level = -1
; You cannot specify additional output handlers if zlib.output_compression
; is activated here. This setting does the same as output_handler but in
; a different order.
; http://php.net/zlib.output-handler
;zlib.output_handler =
; Implicit flush tells PHP to tell the output layer to flush itself
; automatically after every output block. This is equivalent to calling the
; PHP function flush() after each and every call to print() or echo() and each
; and every HTML block. Turning this option on has serious performance
; implications and is generally recommended for debugging purposes only.
; http://php.net/implicit-flush
; Note: This directive is hardcoded to On for the CLI SAPI
implicit_flush = Off
; The unserialize callback function will be called (with the undefined class'
; name as parameter), if the unserializer finds an undefined class
; which should be instantiated. A warning appears if the specified function is
; not defined, or if the function doesn't include/implement the missing class.
; So only set this entry, if you really want to implement such a
; callback-function.
unserialize_callback_func =
; When floats & doubles are serialized store serialize_precision significant
; digits after the floating point. The default value ensures that when floats
; are decoded with unserialize, the data will remain the same.
;change from 17 to 16 to fix json_encode float bug by wangdanfeng
serialize_precision = 16
; open_basedir, if set, limits all file operations to the defined directory
; and below. This directive makes most sense if used in a per-directory
; or per-virtualhost web server configuration file.
; http://php.net/open-basedir
;open_basedir =
; This directive allows you to disable certain functions for security reasons.
; It receives a comma-delimited list of function names.
; http://php.net/disable-functions
disable_functions =
; This directive allows you to disable certain classes for security reasons.
; It receives a comma-delimited list of class names.
; http://php.net/disable-classes
disable_classes =
; Colors for Syntax Highlighting mode. Anything that's acceptable in
; <span style="color: ???????"> would work.
; http://php.net/syntax-highlighting
;highlight.string = #DD0000
;highlight.comment = #FF9900
;highlight.keyword = #007700
;highlight.default = #0000BB
;highlight.html = #000000
; If enabled, the request will be allowed to complete even if the user aborts
; the request. Consider enabling it if executing long requests, which may end up
; being interrupted by the user or a browser timing out. PHP's default behavior
; is to disable this feature.
; http://php.net/ignore-user-abort
;ignore_user_abort = On
; Determines the size of the realpath cache to be used by PHP. This value should
; be increased on systems where PHP opens many files to reflect the quantity of
; the file operations performed.
; http://php.net/realpath-cache-size
;realpath_cache_size = 4096k
; Duration of time, in seconds for which to cache realpath information for a given
; file or directory. For systems with rarely changing files, consider increasing this
; value.
; http://php.net/realpath-cache-ttl
;realpath_cache_ttl = 120
; Enables or disables the circular reference collector.
; http://php.net/zend.enable-gc
zend.enable_gc = On
; If enabled, scripts may be written in encodings that are incompatible with
; the scanner. CP936, Big5, CP949 and Shift_JIS are the examples of such
; encodings. To use this feature, mbstring extension must be enabled.
; Default: Off
;zend.multibyte = Off
; Allows to set the default encoding for the scripts. This value will be used
; unless "declare(encoding=...)" directive appears at the top of the script.
; Only affects if zend.multibyte is set.
; Default: ""
;zend.script_encoding =
;;;;;;;;;;;;;;;;;
; Miscellaneous ;
;;;;;;;;;;;;;;;;;
; Decides whether PHP may expose the fact that it is installed on the server
; (e.g. by adding its signature to the Web server header). It is no security
; threat in any way, but it makes it possible to determine whether you use PHP
; on your server or not.
; http://php.net/expose-php
expose_php = Off
;;;;;;;;;;;;;;;;;;;
; Resource Limits ;
;;;;;;;;;;;;;;;;;;;
; Maximum execution time of each script, in seconds
; http://php.net/max-execution-time
; Note: This directive is hardcoded to 0 for the CLI SAPI
max_execution_time = 30
; Maximum amount of time each script may spend parsing request data. It's a good
; idea to limit this time on productions servers in order to eliminate unexpectedly
; long running scripts.
; Note: This directive is hardcoded to -1 for the CLI SAPI
; Default Value: -1 (Unlimited)
; Development Value: 60 (60 seconds)
; Production Value: 60 (60 seconds)
; http://php.net/max-input-time
max_input_time = 60
; Maximum input variable nesting level
; http://php.net/max-input-nesting-level
;max_input_nesting_level = 64
; How many GET/POST/COOKIE input variables may be accepted
; max_input_vars = 1000
; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit=128M
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Error handling and logging ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; This directive informs PHP of which errors, warnings and notices you would like
; it to take action for. The recommended way of setting values for this
; directive is through the use of the error level constants and bitwise
; operators. The error level constants are below here for convenience as well as
; some common settings and their meanings.
; By default, PHP is set to take action on all errors, notices and warnings EXCEPT
; those related to E_NOTICE and E_STRICT, which together cover best practices and
; recommended coding standards in PHP. For performance reasons, this is the
; recommend error reporting setting. Your production server shouldn't be wasting
; resources complaining about best practices and coding standards. That's what
; development servers and development settings are for.
; Note: The php.ini-development file has this setting as E_ALL. This
; means it pretty much reports everything which is exactly what you want during
; development and early testing.
;
; Error Level Constants:
; E_ALL - All errors and warnings (includes E_STRICT as of PHP 5.4.0)
; E_ERROR - fatal run-time errors
; E_RECOVERABLE_ERROR - almost fatal run-time errors
; E_WARNING - run-time warnings (non-fatal errors)
; E_PARSE - compile-time parse errors
; E_NOTICE - run-time notices (these are warnings which often result
; from a bug in your code, but it's possible that it was
; intentional (e.g., using an uninitialized variable and
; relying on the fact it is automatically initialized to an
; empty string)
; E_STRICT - run-time notices, enable to have PHP suggest changes
; to your code which will ensure the best interoperability
; and forward compatibility of your code
; E_CORE_ERROR - fatal errors that occur during PHP's initial startup
; E_CORE_WARNING - warnings (non-fatal errors) that occur during PHP's
; initial startup
; E_COMPILE_ERROR - fatal compile-time errors
; E_COMPILE_WARNING - compile-time warnings (non-fatal errors)
; E_USER_ERROR - user-generated error message
; E_USER_WARNING - user-generated warning message
; E_USER_NOTICE - user-generated notice message
; E_DEPRECATED - warn about code that will not work in future versions
; of PHP
; E_USER_DEPRECATED - user-generated deprecation warnings
;
; Common Values:
; E_ALL (Show all errors, warnings and notices including coding standards.)
; E_ALL & ~E_NOTICE (Show all errors, except for notices)
; E_ALL & ~E_NOTICE & ~E_STRICT (Show all errors, except for notices and coding standards warnings.)
; E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR (Show only errors)
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; http://php.net/error-reporting
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
; This directive controls whether or not and where PHP will output errors,
; notices and warnings too. Error output is very useful during development, but
; it could be very dangerous in production environments. Depending on the code
; which is triggering the error, sensitive information could potentially leak
; out of your application such as database usernames and passwords or worse.
; For production environments, we recommend logging errors rather than
; sending them to STDOUT.
; Possible Values:
; Off = Do not display any errors
; stderr = Display errors to STDERR (affects only CGI/CLI binaries!)
; On or stdout = Display errors to STDOUT
; Default Value: On
; Development Value: On
; Production Value: Off
; http://php.net/display-errors
display_errors = On
; The display of errors which occur during PHP's startup sequence are handled
; separately from display_errors. PHP's default behavior is to suppress those
; errors from clients. Turning the display of startup errors on can be useful in
; debugging configuration problems. We strongly recommend you
; set this to 'off' for production servers.
; Default Value: Off
; Development Value: On
; Production Value: Off
; http://php.net/display-startup-errors
display_startup_errors = Off
; Besides displaying errors, PHP can also log errors to locations such as a
; server-specific log, STDERR, or a location specified by the error_log
; directive found below. While errors should not be displayed on productions
; servers they should still be monitored and logging is a great way to do that.
; Default Value: Off
; Development Value: On
; Production Value: On
; http://php.net/log-errors
log_errors = On
; Set maximum length of log_errors. In error_log information about the source is
; added. The default is 1024 and 0 allows to not apply any maximum length at all.
; http://php.net/log-errors-max-len
log_errors_max_len = 1024
; Do not log repeated messages. Repeated errors must occur in same file on same
; line unless ignore_repeated_source is set true.
; http://php.net/ignore-repeated-errors
ignore_repeated_errors = Off
; Ignore source of message when ignoring repeated messages. When this setting
; is On you will not log errors with repeated messages from different files or
; source lines.
; http://php.net/ignore-repeated-source
ignore_repeated_source = Off
; If this parameter is set to Off, then memory leaks will not be shown (on
; stdout or in the log). This has only effect in a debug compile, and if
; error reporting includes E_WARNING in the allowed list
; http://php.net/report-memleaks
report_memleaks = On
; This setting is on by default.
;report_zend_debug = 0
; Store the last error/warning message in $php_errormsg (boolean). Setting this value
; to On can assist in debugging and is appropriate for development servers. It should
; however be disabled on production servers.
; Default Value: Off
; Development Value: On
; Production Value: Off
; http://php.net/track-errors
track_errors = Off
; Turn off normal error reporting and emit XML-RPC error XML
; http://php.net/xmlrpc-errors
;xmlrpc_errors = 0
; An XML-RPC faultCode
;xmlrpc_error_number = 0
; When PHP displays or logs an error, it has the capability of formatting the
; error message as HTML for easier reading. This directive controls whether
; the error message is formatted as HTML or not.
; Note: This directive is hardcoded to Off for the CLI SAPI
; Default Value: On
; Development Value: On
; Production value: On
; http://php.net/html-errors
html_errors = On
; If html_errors is set to On *and* docref_root is not empty, then PHP
; produces clickable error messages that direct to a page describing the error
; or function causing the error in detail.
; You can download a copy of the PHP manual from http://php.net/docs
; and change docref_root to the base URL of your local copy including the
; leading '/'. You must also specify the file extension being used including
; the dot. PHP's default behavior is to leave these settings empty, in which
; case no links to documentation are generated.
; Note: Never use this feature for production boxes.
; http://php.net/docref-root
; Examples
;docref_root = "/phpmanual/"
; http://php.net/docref-ext
;docref_ext = .html
; String to output before an error message. PHP's default behavior is to leave
; this setting blank.
; http://php.net/error-prepend-string
; Example:
;error_prepend_string = "<span style='color: #ff0000'>"
; String to output after an error message. PHP's default behavior is to leave
; this setting blank.
; http://php.net/error-append-string
; Example:
;error_append_string = "</span>"
; Log errors to specified file. PHP's default behavior is to leave this value
; empty.
; http://php.net/error-log
; Example:
error_log = /home/services/api.go2yd.com/logs/php-error.log
; Log errors to syslog (Event Log on Windows).
;error_log = syslog
;windows.show_crt_warning
; Default value: 0
; Development value: 0
; Production value: 0
;;;;;;;;;;;;;;;;;
; Data Handling ;
;;;;;;;;;;;;;;;;;
; The separator used in PHP generated URLs to separate arguments.
; PHP's default setting is "&".
; http://php.net/arg-separator.output
; Example:
;arg_separator.output = "&amp;"
; List of separator(s) used by PHP to parse input URLs into variables.
; PHP's default setting is "&".
; NOTE: Every character in this directive is considered as separator!
; http://php.net/arg-separator.input
; Example:
;arg_separator.input = ";&"
; This directive determines which super global arrays are registered when PHP
; starts up. G,P,C,E & S are abbreviations for the following respective super
; globals: GET, POST, COOKIE, ENV and SERVER. There is a performance penalty
; paid for the registration of these arrays and because ENV is not as commonly
; used as the others, ENV is not recommended on productions servers. You
; can still get access to the environment variables through getenv() should you
; need to.
; Default Value: "EGPCS"
; Development Value: "GPCS"
; Production Value: "GPCS";
; http://php.net/variables-order
variables_order = "GPCS"
; This directive determines which super global data (G,P & C) should be
; registered into the super global array REQUEST. If so, it also determines
; the order in which that data is registered. The values for this directive
; are specified in the same manner as the variables_order directive,
; EXCEPT one. Leaving this value empty will cause PHP to use the value set
; in the variables_order directive. It does not mean it will leave the super
; globals array REQUEST empty.
; Default Value: None
; Development Value: "GP"
; Production Value: "GP"
; http://php.net/request-order
request_order = "GP"
; This directive determines whether PHP registers $argv & $argc each time it
; runs. $argv contains an array of all the arguments passed to PHP when a script
; is invoked. $argc contains an integer representing the number of arguments
; that were passed when the script was invoked. These arrays are extremely
; useful when running scripts from the command line. When this directive is
; enabled, registering these variables consumes CPU cycles and memory each time
; a script is executed. For performance reasons, this feature should be disabled
; on production servers.
; Note: This directive is hardcoded to On for the CLI SAPI
; Default Value: On
; Development Value: Off
; Production Value: Off
; http://php.net/register-argc-argv
register_argc_argv = Off
; When enabled, the ENV, REQUEST and SERVER variables are created when they're
; first used (Just In Time) instead of when the script starts. If these
; variables are not used within a script, having this directive on will result
; in a performance gain. The PHP directive register_argc_argv must be disabled
; for this directive to have any affect.
; http://php.net/auto-globals-jit
auto_globals_jit = On
; Whether PHP will read the POST data.
; This option is enabled by default.
; Most likely, you won't want to disable this option globally. It causes $_POST
; and $_FILES to always be empty; the only way you will be able to read the
; POST data will be through the php://input stream wrapper. This can be useful
; to proxy requests or to process the POST data in a memory efficient fashion.
; http://php.net/enable-post-data-reading
;enable_post_data_reading = Off
; Maximum size of POST data that PHP will accept.
; Its value may be 0 to disable the limit. It is ignored if POST data reading
; is disabled through enable_post_data_reading.
; http://php.net/post-max-size
post_max_size = 8M
; Automatically add files before PHP document.
; http://php.net/auto-prepend-file
auto_prepend_file =
; Automatically add files after PHP document.
; http://php.net/auto-append-file
auto_append_file =
; By default, PHP will output a media type using the Content-Type header. To
; disable this, simply set it to be empty.
;
; PHP's built-in default media type is set to text/html.
; http://php.net/default-mimetype
default_mimetype = "text/html"
; PHP's default character set is set to UTF-8.
; http://php.net/default-charset
default_charset = "UTF-8"
; PHP internal character encoding is set to empty.
; If empty, default_charset is used.
; http://php.net/internal-encoding
;internal_encoding =
; PHP input character encoding is set to empty.
; If empty, default_charset is used.
; http://php.net/input-encoding
;input_encoding =
; PHP output character encoding is set to empty.
; If empty, default_charset is used.
; See also output_buffer.
; http://php.net/output-encoding
;output_encoding =
;;;;;;;;;;;;;;;;;;;;;;;;;
; Paths and Directories ;
;;;;;;;;;;;;;;;;;;;;;;;;;
; UNIX: "/path1:/path2"
;include_path = ".:/php/includes"
;
; Windows: "\path1;\path2"
;include_path = ".;c:\php\includes"
;
; PHP's default setting for include_path is ".;/path/to/php/pear"
; http://php.net/include-path
; The root of the PHP pages, used only if nonempty.
; if PHP was not compiled with FORCE_REDIRECT, you SHOULD set doc_root
; if you are running php as a CGI under any web server (other than IIS)
; see documentation for security issues. The alternate is to use the
; cgi.force_redirect configuration below
; http://php.net/doc-root
doc_root =
; The directory under which PHP opens the script using /~username used only
; if nonempty.
; http://php.net/user-dir
user_dir =
; Directory in which the loadable extensions (modules) reside.
; http://php.net/extension-dir
; extension_dir = "./"
; On windows:
; extension_dir = "ext"
; Directory where the temporary files should be placed.
; Defaults to the system default (see sys_get_temp_dir)
; sys_temp_dir = "/tmp"
; Whether or not to enable the dl() function. The dl() function does NOT work
; properly in multithreaded servers, such as IIS or Zeus, and is automatically
; disabled on them.
; http://php.net/enable-dl
enable_dl = Off
; cgi.force_redirect is necessary to provide security running PHP as a CGI under
; most web servers. Left undefined, PHP turns this on by default. You can
; turn it off here AT YOUR OWN RISK
; **You CAN safely turn this off for IIS, in fact, you MUST.**
; http://php.net/cgi.force-redirect
;cgi.force_redirect = 1
; if cgi.nph is enabled it will force cgi to always sent Status: 200 with
; every request. PHP's default behavior is to disable this feature.
;cgi.nph = 1
; if cgi.force_redirect is turned on, and you are not running under Apache or Netscape
; (iPlanet) web servers, you MAY need to set an environment variable name that PHP
; will look for to know it is OK to continue execution. Setting this variable MAY
; cause security issues, KNOW WHAT YOU ARE DOING FIRST.
; http://php.net/cgi.redirect-status-env
;cgi.redirect_status_env =
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting
; this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting
; of zero causes PHP to behave as before. Default is 1. You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
; http://php.net/cgi.fix-pathinfo
;cgi.fix_pathinfo=1
; if cgi.discard_path is enabled, the PHP CGI binary can safely be placed outside
; of the web tree and people will not be able to circumvent .htaccess security.
; http://php.net/cgi.dicard-path
;cgi.discard_path=1
; FastCGI under IIS (on WINNT based OS) supports the ability to impersonate
; security tokens of the calling client. This allows IIS to define the
; security context that the request runs under. mod_fastcgi under Apache
; does not currently support this feature (03/17/2002)
; Set to 1 if running under IIS. Default is zero.
; http://php.net/fastcgi.impersonate
;fastcgi.impersonate = 1
; Disable logging through FastCGI connection. PHP's default behavior is to enable
; this feature.
;fastcgi.logging = 0
; cgi.rfc2616_headers configuration option tells PHP what type of headers to
; use when sending HTTP response code. If set to 0, PHP sends Status: header that
; is supported by Apache. When this option is set to 1, PHP will send
; RFC2616 compliant header.
; Default is zero.
; http://php.net/cgi.rfc2616-headers
;cgi.rfc2616_headers = 0
; cgi.check_shebang_line controls whether CGI PHP checks for line starting with #!
; (shebang) at the top of the running script. This line might be needed if the
; script support running both as stand-alone script and via PHP CGI<. PHP in CGI
; mode skips this line and ignores its content if this directive is turned on.
; http://php.net/cgi.check-shebang-line
;cgi.check_shebang_line=1
;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;
; Whether to allow HTTP file uploads.
; http://php.net/file-uploads
file_uploads = On
; Temporary directory for HTTP uploaded files (will use system default if not
; specified).
; http://php.net/upload-tmp-dir
;upload_tmp_dir =
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 8M
; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20
;;;;;;;;;;;;;;;;;;
; Fopen wrappers ;
;;;;;;;;;;;;;;;;;;
; Whether to allow the treatment of URLs (like http:// or ftp://) as files.
; http://php.net/allow-url-fopen
allow_url_fopen = On
; Whether to allow include/require to open URLs (like http:// or ftp://) as files.
; http://php.net/allow-url-include
allow_url_include = Off
; Define the anonymous ftp password (your email address). PHP's default setting
; for this is empty.
; http://php.net/from
;from="john@doe.com"
; Define the User-Agent string. PHP's default setting for this is empty.
; http://php.net/user-agent
;user_agent="PHP"
; Default timeout for socket based streams (seconds)
; http://php.net/default-socket-timeout
default_socket_timeout = 60
; If your scripts have to deal with files from Macintosh systems,
; or you are running on a Mac and need to deal with files from
; unix or win32 systems, setting this flag will cause PHP to
; automatically detect the EOL character in those files so that
; fgets() and file() will work regardless of the source of the file.
; http://php.net/auto-detect-line-endings
;auto_detect_line_endings = Off
;;;;;;;;;;;;;;;;;;;;;;
; Dynamic Extensions ;
;;;;;;;;;;;;;;;;;;;;;;
; If you wish to have an extension loaded automatically, use the following
; syntax:
;
; extension=modulename.extension
;
; For example, on Windows:
;
; extension=msql.dll
;
; ... or under UNIX:
;
; extension=msql.so
;
; ... or with a path:
;
; extension=/path/to/extension/msql.so
;
; If you only provide the name of the extension, PHP will look for it in its
; default extension directory.
; The MIBS data available in the PHP distribution must be installed.
; See http://www.php.net/manual/en/snmp.installation.php
extension=apcu.so
extension=igbinary.so
extension=msgpack.so
extension=redis.so
extension=memcached.so
extension=mongodb.so
extension=rdkafka.so
extension=yaconf.so
zend_extension=opcache.so
extension=protobuf.so
extension=mcrypt.so
extension=yaf.so
yaf.environ=dev
yaf.use_namespace=1
yaf.use_spl_autoload=1
;;;;;;;;;;;;;;;;;;;
; Module Settings ;
;;;;;;;;;;;;;;;;;;;
[CLI Server]
; Whether the CLI web server uses ANSI color coding in its terminal output.
cli_server.color = On
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone =Asia/Shanghai
; http://php.net/date.default-latitude
;date.default_latitude = 31.7667
; http://php.net/date.default-longitude
;date.default_longitude = 35.2333
; http://php.net/date.sunrise-zenith
;date.sunrise_zenith = 90.583333
; http://php.net/date.sunset-zenith
;date.sunset_zenith = 90.583333
[filter]
; http://php.net/filter.default
;filter.default = unsafe_raw
; http://php.net/filter.default-flags
;filter.default_flags =
[iconv]
; Use of this INI entry is deprecated, use global input_encoding instead.
; If empty, default_charset or input_encoding or iconv.input_encoding is used.
; The precedence is: default_charset < intput_encoding < iconv.input_encoding
;iconv.input_encoding =
; Use of this INI entry is deprecated, use global internal_encoding instead.
; If empty, default_charset or internal_encoding or iconv.internal_encoding is used.
; The precedence is: default_charset < internal_encoding < iconv.internal_encoding
;iconv.internal_encoding =
; Use of this INI entry is deprecated, use global output_encoding instead.
; If empty, default_charset or output_encoding or iconv.output_encoding is used.
; The precedence is: default_charset < output_encoding < iconv.output_encoding
; To use an output encoding conversion, iconv's output handler must be set
; otherwise output encoding conversion cannot be performed.
;iconv.output_encoding =
[intl]
;intl.default_locale =
; This directive allows you to produce PHP errors when some error
; happens within intl functions. The value is the level of the error produced.
; Default is 0, which does not produce any errors.
;intl.error_level = E_WARNING
;intl.use_exceptions = 0
[sqlite3]
;sqlite3.extension_dir =
[Pcre]
;PCRE library backtracking limit.
; http://php.net/pcre.backtrack-limit
;pcre.backtrack_limit=100000
;PCRE library recursion limit.
;Please note that if you set this value to a high number you may consume all
;the available process stack and eventually crash PHP (due to reaching the
;stack size limit imposed by the Operating System).
; http://php.net/pcre.recursion-limit
;pcre.recursion_limit=100000
;Enables or disables JIT compilation of patterns. This requires the PCRE
;library to be compiled with JIT support.
;pcre.jit=1
[Pdo]
; Whether to pool ODBC connections. Can be one of "strict", "relaxed" or "off"
; http://php.net/pdo-odbc.connection-pooling
;pdo_odbc.connection_pooling=strict
;pdo_odbc.db2_instance_name
[Pdo_mysql]
; If mysqlnd is used: Number of cache slots for the internal result set cache
; http://php.net/pdo_mysql.cache_size
pdo_mysql.cache_size = 2000
; Default socket name for local MySQL connects. If empty, uses the built-in
; MySQL defaults.
; http://php.net/pdo_mysql.default-socket
pdo_mysql.default_socket=
[Phar]
; http://php.net/phar.readonly
;phar.readonly = On
; http://php.net/phar.require-hash
;phar.require_hash = On
;phar.cache_list =
[mail function]
; For Win32 only.
; http://php.net/smtp
SMTP = localhost
; http://php.net/smtp-port
smtp_port = 25
; For Win32 only.
; http://php.net/sendmail-from
;sendmail_from = me@example.com
; For Unix only. You may supply arguments as well (default: "sendmail -t -i").
; http://php.net/sendmail-path
;sendmail_path =
; Force the addition of the specified parameters to be passed as extra parameters
; to the sendmail binary. These parameters will always replace the value of
; the 5th parameter to mail().
;mail.force_extra_parameters =
; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename
mail.add_x_header = On
; The path to a log file that will log all mail() calls. Log entries include
; the full path of the script, line number, To address and headers.
;mail.log =
; Log mail to syslog (Event Log on Windows).
;mail.log = syslog
[SQL]
; http://php.net/sql.safe-mode
sql.safe_mode = Off
[ODBC]
; http://php.net/odbc.default-db
;odbc.default_db = Not yet implemented
; http://php.net/odbc.default-user
;odbc.default_user = Not yet implemented
; http://php.net/odbc.default-pw
;odbc.default_pw = Not yet implemented
; Controls the ODBC cursor model.
; Default: SQL_CURSOR_STATIC (default).
;odbc.default_cursortype
; Allow or prevent persistent links.
; http://php.net/odbc.allow-persistent
odbc.allow_persistent = On
; Check that a connection is still valid before reuse.
; http://php.net/odbc.check-persistent
odbc.check_persistent = On
; Maximum number of persistent links. -1 means no limit.
; http://php.net/odbc.max-persistent
odbc.max_persistent = -1
; Maximum number of links (persistent + non-persistent). -1 means no limit.
; http://php.net/odbc.max-links
odbc.max_links = -1
; Handling of LONG fields. Returns number of bytes to variables. 0 means
; passthru.
; http://php.net/odbc.defaultlrl
odbc.defaultlrl = 4096
; Handling of binary data. 0 means passthru, 1 return as is, 2 convert to char.
; See the documentation on odbc_binmode and odbc_longreadlen for an explanation
; of odbc.defaultlrl and odbc.defaultbinmode
; http://php.net/odbc.defaultbinmode
odbc.defaultbinmode = 1
;birdstep.max_links = -1
[Interbase]
; Allow or prevent persistent links.
ibase.allow_persistent = 1
; Maximum number of persistent links. -1 means no limit.
ibase.max_persistent = -1
; Maximum number of links (persistent + non-persistent). -1 means no limit.
ibase.max_links = -1
; Default database name for ibase_connect().
;ibase.default_db =
; Default username for ibase_connect().
;ibase.default_user =
; Default password for ibase_connect().
;ibase.default_password =
; Default charset for ibase_connect().
;ibase.default_charset =
; Default timestamp format.
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
; Default date format.
ibase.dateformat = "%Y-%m-%d"
; Default time format.
ibase.timeformat = "%H:%M:%S"
[MySQLi]
; Maximum number of persistent links. -1 means no limit.
; http://php.net/mysqli.max-persistent
mysqli.max_persistent = -1
; Allow accessing, from PHP's perspective, local files with LOAD DATA statements
; http://php.net/mysqli.allow_local_infile
;mysqli.allow_local_infile = On
; Allow or prevent persistent links.
; http://php.net/mysqli.allow-persistent
mysqli.allow_persistent = On
; Maximum number of links. -1 means no limit.
; http://php.net/mysqli.max-links
mysqli.max_links = -1
; If mysqlnd is used: Number of cache slots for the internal result set cache
; http://php.net/mysqli.cache_size
mysqli.cache_size = 2000
; Default port number for mysqli_connect(). If unset, mysqli_connect() will use
; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the
; compile-time value defined MYSQL_PORT (in that order). Win32 will only look
; at MYSQL_PORT.
; http://php.net/mysqli.default-port
mysqli.default_port = 3306
; Default socket name for local MySQL connects. If empty, uses the built-in
; MySQL defaults.
; http://php.net/mysqli.default-socket
mysqli.default_socket =
; Default host for mysql_connect() (doesn't apply in safe mode).
; http://php.net/mysqli.default-host
mysqli.default_host =
; Default user for mysql_connect() (doesn't apply in safe mode).
; http://php.net/mysqli.default-user
mysqli.default_user =
; Default password for mysqli_connect() (doesn't apply in safe mode).
; Note that this is generally a *bad* idea to store passwords in this file.
; *Any* user with PHP access can run 'echo get_cfg_var("mysqli.default_pw")
; and reveal this password! And of course, any users with read access to this
; file will be able to reveal the password as well.
; http://php.net/mysqli.default-pw
mysqli.default_pw =
; Allow or prevent reconnect
mysqli.reconnect = Off
[mysqlnd]
; Enable / Disable collection of general statistics by mysqlnd which can be
; used to tune and monitor MySQL operations.
; http://php.net/mysqlnd.collect_statistics
mysqlnd.collect_statistics = Off
; Enable / Disable collection of memory usage statistics by mysqlnd which can be
; used to tune and monitor MySQL operations.
; http://php.net/mysqlnd.collect_memory_statistics
mysqlnd.collect_memory_statistics = Off
; Records communication from all extensions using mysqlnd to the specified log
; file.
; http://php.net/mysqlnd.debug
;mysqlnd.debug =
; Defines which queries will be logged.
; http://php.net/mysqlnd.log_mask
;mysqlnd.log_mask = 0
; Default size of the mysqlnd memory pool, which is used by result sets.
; http://php.net/mysqlnd.mempool_default_size
;mysqlnd.mempool_default_size = 16000
; Size of a pre-allocated buffer used when sending commands to MySQL in bytes.
; http://php.net/mysqlnd.net_cmd_buffer_size
;mysqlnd.net_cmd_buffer_size = 2048
; Size of a pre-allocated buffer used for reading data sent by the server in
; bytes.
; http://php.net/mysqlnd.net_read_buffer_size
;mysqlnd.net_read_buffer_size = 32768
; Timeout for network requests in seconds.
; http://php.net/mysqlnd.net_read_timeout
;mysqlnd.net_read_timeout = 31536000
; SHA-256 Authentication Plugin related. File with the MySQL server public RSA
; key.
; http://php.net/mysqlnd.sha256_server_public_key
;mysqlnd.sha256_server_public_key =
[OCI8]
; Connection: Enables privileged connections using external
; credentials (OCI_SYSOPER, OCI_SYSDBA)
; http://php.net/oci8.privileged-connect
;oci8.privileged_connect = Off
; Connection: The maximum number of persistent OCI8 connections per
; process. Using -1 means no limit.
; http://php.net/oci8.max-persistent
;oci8.max_persistent = -1
; Connection: The maximum number of seconds a process is allowed to
; maintain an idle persistent connection. Using -1 means idle
; persistent connections will be maintained forever.
; http://php.net/oci8.persistent-timeout
;oci8.persistent_timeout = -1
; Connection: The number of seconds that must pass before issuing a
; ping during oci_pconnect() to check the connection validity. When
; set to 0, each oci_pconnect() will cause a ping. Using -1 disables
; pings completely.
; http://php.net/oci8.ping-interval
;oci8.ping_interval = 60
; Connection: Set this to a user chosen connection class to be used
; for all pooled server requests with Oracle 11g Database Resident
; Connection Pooling (DRCP). To use DRCP, this value should be set to
; the same string for all web servers running the same application,
; the database pool must be configured, and the connection string must
; specify to use a pooled server.
;oci8.connection_class =
; High Availability: Using On lets PHP receive Fast Application
; Notification (FAN) events generated when a database node fails. The
; database must also be configured to post FAN events.
;oci8.events = Off
; Tuning: This option enables statement caching, and specifies how
; many statements to cache. Using 0 disables statement caching.
; http://php.net/oci8.statement-cache-size
;oci8.statement_cache_size = 20
; Tuning: Enables statement prefetching and sets the default number of
; rows that will be fetched automatically after statement execution.
; http://php.net/oci8.default-prefetch
;oci8.default_prefetch = 100
; Compatibility. Using On means oci_close() will not close
; oci_connect() and oci_new_connect() connections.
; http://php.net/oci8.old-oci-close-semantics
;oci8.old_oci_close_semantics = Off
[PostgreSQL]
; Allow or prevent persistent links.
; http://php.net/pgsql.allow-persistent
pgsql.allow_persistent = On
; Detect broken persistent links always with pg_pconnect().
; Auto reset feature requires a little overheads.
; http://php.net/pgsql.auto-reset-persistent
pgsql.auto_reset_persistent = Off
; Maximum number of persistent links. -1 means no limit.
; http://php.net/pgsql.max-persistent
pgsql.max_persistent = -1
; Maximum number of links (persistent+non persistent). -1 means no limit.
; http://php.net/pgsql.max-links
pgsql.max_links = -1
; Ignore PostgreSQL backends Notice message or not.
; Notice message logging require a little overheads.
; http://php.net/pgsql.ignore-notice
pgsql.ignore_notice = 0
; Log PostgreSQL backends Notice message or not.
; Unless pgsql.ignore_notice=0, module cannot log notice message.
; http://php.net/pgsql.log-notice
pgsql.log_notice = 0
[bcmath]
; Number of decimal digits for all bcmath functions.
; http://php.net/bcmath.scale
bcmath.scale = 0
[browscap]
; http://php.net/browscap
;browscap = extra/browscap.ini
[Session]
; Handler used to store/retrieve data.
; http://php.net/session.save-handler
session.save_handler = files
; Argument passed to save_handler. In the case of files, this is the path
; where data files are stored. Note: Windows users have to change this
; variable in order to use PHP's session functions.
;
; The path can be defined as:
;
; session.save_path = "N;/path"
;
; where N is an integer. Instead of storing all the session files in
; /path, what this will do is use subdirectories N-levels deep, and
; store the session data in those directories. This is useful if
; your OS has problems with many files in one directory, and is
; a more efficient layout for servers that handle many sessions.
;
; NOTE 1: PHP will not create this directory structure automatically.
; You can use the script in the ext/session dir for that purpose.
; NOTE 2: See the section on garbage collection below if you choose to
; use subdirectories for session storage
;
; The file storage module creates files using mode 600 by default.
; You can change that by using
;
; session.save_path = "N;MODE;/path"
;
; where MODE is the octal representation of the mode. Note that this
; does not overwrite the process's umask.
; http://php.net/session.save-path
;session.save_path = "/tmp"
; Whether to use strict session mode.
; Strict session mode does not accept uninitialized session ID and regenerate
; session ID if browser sends uninitialized session ID. Strict mode protects
; applications from session fixation via session adoption vulnerability. It is
; disabled by default for maximum compatibility, but enabling it is encouraged.
; https://wiki.php.net/rfc/strict_sessions
session.use_strict_mode = 0
; Whether to use cookies.
; http://php.net/session.use-cookies
session.use_cookies = 1
; http://php.net/session.cookie-secure
;session.cookie_secure =
; This option forces PHP to fetch and use a cookie for storing and maintaining
; the session id. We encourage this operation as it's very helpful in combating
; session hijacking when not specifying and managing your own session id. It is
; not the be-all and end-all of session hijacking defense, but it's a good start.
; http://php.net/session.use-only-cookies
session.use_only_cookies = 1
; Name of the session (used as cookie name).
; http://php.net/session.name
session.name = PHPSESSID
; Initialize session on request startup.
; http://php.net/session.auto-start
session.auto_start = 0
; Lifetime in seconds of cookie or, if 0, until browser is restarted.
; http://php.net/session.cookie-lifetime
session.cookie_lifetime = 0
; The path for which the cookie is valid.
; http://php.net/session.cookie-path
session.cookie_path = /
; The domain for which the cookie is valid.
; http://php.net/session.cookie-domain
session.cookie_domain =
; Whether or not to add the httpOnly flag to the cookie, which makes it inaccessible to browser scripting languages such as JavaScript.
; http://php.net/session.cookie-httponly
session.cookie_httponly =
; Handler used to serialize data. php is the standard serializer of PHP.
; http://php.net/session.serialize-handler
session.serialize_handler = php
; Defines the probability that the 'garbage collection' process is started
; on every session initialization. The probability is calculated by using
; gc_probability/gc_divisor. Where session.gc_probability is the numerator
; and gc_divisor is the denominator in the equation. Setting this value to 1
; when the session.gc_divisor value is 100 will give you approximately a 1% chance
; the gc will run on any give request.
; Default Value: 1
; Development Value: 1
; Production Value: 1
; http://php.net/session.gc-probability
session.gc_probability = 1
; Defines the probability that the 'garbage collection' process is started on every
; session initialization. The probability is calculated by using the following equation:
; gc_probability/gc_divisor. Where session.gc_probability is the numerator and
; session.gc_divisor is the denominator in the equation. Setting this value to 1
; when the session.gc_divisor value is 100 will give you approximately a 1% chance
; the gc will run on any give request. Increasing this value to 1000 will give you
; a 0.1% chance the gc will run on any give request. For high volume production servers,
; this is a more efficient approach.
; Default Value: 100
; Development Value: 1000
; Production Value: 1000
; http://php.net/session.gc-divisor
session.gc_divisor = 1000
; After this number of seconds, stored data will be seen as 'garbage' and
; cleaned up by the garbage collection process.
; http://php.net/session.gc-maxlifetime
session.gc_maxlifetime = 1440
; NOTE: If you are using the subdirectory option for storing session files
; (see session.save_path above), then garbage collection does *not*
; happen automatically. You will need to do your own garbage
; collection through a shell script, cron entry, or some other method.
; For example, the following script would is the equivalent of
; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):
; find /path/to/sessions -cmin +24 -type f | xargs rm
; Check HTTP Referer to invalidate externally stored URLs containing ids.
; HTTP_REFERER has to contain this substring for the session to be
; considered as valid.
; http://php.net/session.referer-check
session.referer_check =
; How many bytes to read from the file.
; http://php.net/session.entropy-length
;session.entropy_length = 32
; Specified here to create the session id.
; http://php.net/session.entropy-file
; Defaults to /dev/urandom
; On systems that don't have /dev/urandom but do have /dev/arandom, this will default to /dev/arandom
; If neither are found at compile time, the default is no entropy file.
; On windows, setting the entropy_length setting will activate the
; Windows random source (using the CryptoAPI)
;session.entropy_file = /dev/urandom
; Set to {nocache,private,public,} to determine HTTP caching aspects
; or leave this empty to avoid sending anti-caching headers.
; http://php.net/session.cache-limiter
session.cache_limiter = nocache
; Document expires after n minutes.
; http://php.net/session.cache-expire
session.cache_expire = 180
; trans sid support is disabled by default.
; Use of trans sid may risk your users' security.
; Use this option with caution.
; - User may send URL contains active session ID
; to other person via. email/irc/etc.
; - URL that contains active session ID may be stored
; in publicly accessible computer.
; - User may access your site with the same session ID
; always using URL stored in browser's history or bookmarks.
; http://php.net/session.use-trans-sid
session.use_trans_sid = 0
; Select a hash function for use in generating session ids.
; Possible Values
; 0 (MD5 128 bits)
; 1 (SHA-1 160 bits)
; This option may also be set to the name of any hash function supported by
; the hash extension. A list of available hashes is returned by the hash_algos()
; function.
; http://php.net/session.hash-function
session.hash_function = 0
; Define how many bits are stored in each character when converting
; the binary hash data to something readable.
; Possible values:
; 4 (4 bits: 0-9, a-f)
; 5 (5 bits: 0-9, a-v)
; 6 (6 bits: 0-9, a-z, A-Z, "-", ",")
; Default Value: 4
; Development Value: 5
; Production Value: 5
; http://php.net/session.hash-bits-per-character
session.hash_bits_per_character = 5
; The URL rewriter will look for URLs in a defined set of HTML tags.
; form/fieldset are special; if you include them here, the rewriter will
; add a hidden <input> field with the info which is otherwise appended
; to URLs. If you want XHTML conformity, remove the form entry.
; Note that all valid entries require a "=", even if no value follows.
; Default Value: "a=href,area=href,frame=src,form=,fieldset="
; Development Value: "a=href,area=href,frame=src,input=src,form=fakeentry"
; Production Value: "a=href,area=href,frame=src,input=src,form=fakeentry"
; http://php.net/url-rewriter.tags
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"
; Enable upload progress tracking in $_SESSION
; Default Value: On
; Development Value: On
; Production Value: On
; http://php.net/session.upload-progress.enabled
;session.upload_progress.enabled = On
; Cleanup the progress information as soon as all POST data has been read
; (i.e. upload completed).
; Default Value: On
; Development Value: On
; Production Value: On
; http://php.net/session.upload-progress.cleanup
;session.upload_progress.cleanup = On
; A prefix used for the upload progress key in $_SESSION
; Default Value: "upload_progress_"
; Development Value: "upload_progress_"
; Production Value: "upload_progress_"
; http://php.net/session.upload-progress.prefix
;session.upload_progress.prefix = "upload_progress_"
; The index name (concatenated with the prefix) in $_SESSION
; containing the upload progress information
; Default Value: "PHP_SESSION_UPLOAD_PROGRESS"
; Development Value: "PHP_SESSION_UPLOAD_PROGRESS"
; Production Value: "PHP_SESSION_UPLOAD_PROGRESS"
; http://php.net/session.upload-progress.name
;session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
; How frequently the upload progress should be updated.
; Given either in percentages (per-file), or in bytes
; Default Value: "1%"
; Development Value: "1%"
; Production Value: "1%"
; http://php.net/session.upload-progress.freq
;session.upload_progress.freq = "1%"
; The minimum delay between updates, in seconds
; Default Value: 1
; Development Value: 1
; Production Value: 1
; http://php.net/session.upload-progress.min-freq
;session.upload_progress.min_freq = "1"
; Only write session data when session data is changed. Enabled by default.
; http://php.net/session.lazy-write
;session.lazy_write = On
[Assertion]
; Switch whether to compile assertions at all (to have no overhead at run-time)
; -1: Do not compile at all
; 0: Jump over assertion at run-time
; 1: Execute assertions
; Changing from or to a negative value is only possible in php.ini! (For turning assertions on and off at run-time, see assert.active, when zend.assertions = 1)
; Default Value: 1
; Development Value: 1
; Production Value: -1
; http://php.net/zend.assertions
zend.assertions = -1
; Assert(expr); active by default.
; http://php.net/assert.active
;assert.active = On
; Throw an AssertationException on failed assertions
; http://php.net/assert.exception
;assert.exception = On
; Issue a PHP warning for each failed assertion. (Overridden by assert.exception if active)
; http://php.net/assert.warning
;assert.warning = On
; Don't bail out by default.
; http://php.net/assert.bail
;assert.bail = Off
; User-function to be called if an assertion fails.
; http://php.net/assert.callback
;assert.callback = 0
; Eval the expression with current error_reporting(). Set to true if you want
; error_reporting(0) around the eval().
; http://php.net/assert.quiet-eval
;assert.quiet_eval = 0
[COM]
; path to a file containing GUIDs, IIDs or filenames of files with TypeLibs
; http://php.net/com.typelib-file
;com.typelib_file =
; allow Distributed-COM calls
; http://php.net/com.allow-dcom
;com.allow_dcom = true
; autoregister constants of a components typlib on com_load()
; http://php.net/com.autoregister-typelib
;com.autoregister_typelib = true
; register constants casesensitive
; http://php.net/com.autoregister-casesensitive
;com.autoregister_casesensitive = false
; show warnings on duplicate constant registrations
; http://php.net/com.autoregister-verbose
;com.autoregister_verbose = true
; The default character set code-page to use when passing strings to and from COM objects.
; Default: system ANSI code page
;com.code_page=
[mbstring]
; language for internal character representation.
; This affects mb_send_mail() and mbstring.detect_order.
; http://php.net/mbstring.language
;mbstring.language = Japanese
; Use of this INI entry is deprecated, use global internal_encoding instead.
; internal/script encoding.
; Some encoding cannot work as internal encoding. (e.g. SJIS, BIG5, ISO-2022-*)
; If empty, default_charset or internal_encoding or iconv.internal_encoding is used.
; The precedence is: default_charset < internal_encoding < iconv.internal_encoding
;mbstring.internal_encoding =
; Use of this INI entry is deprecated, use global input_encoding instead.
; http input encoding.
; mbstring.encoding_traslation = On is needed to use this setting.
; If empty, default_charset or input_encoding or mbstring.input is used.
; The precedence is: default_charset < intput_encoding < mbsting.http_input
; http://php.net/mbstring.http-input
;mbstring.http_input =
; Use of this INI entry is deprecated, use global output_encoding instead.
; http output encoding.
; mb_output_handler must be registered as output buffer to function.
; If empty, default_charset or output_encoding or mbstring.http_output is used.
; The precedence is: default_charset < output_encoding < mbstring.http_output
; To use an output encoding conversion, mbstring's output handler must be set
; otherwise output encoding conversion cannot be performed.
; http://php.net/mbstring.http-output
;mbstring.http_output =
; enable automatic encoding translation according to
; mbstring.internal_encoding setting. Input chars are
; converted to internal encoding by setting this to On.
; Note: Do _not_ use automatic encoding translation for
; portable libs/applications.
; http://php.net/mbstring.encoding-translation
;mbstring.encoding_translation = Off
; automatic encoding detection order.
; "auto" detect order is changed according to mbstring.language
; http://php.net/mbstring.detect-order
;mbstring.detect_order = auto
; substitute_character used when character cannot be converted
; one from another
; http://php.net/mbstring.substitute-character
;mbstring.substitute_character = none
; overload(replace) single byte functions by mbstring functions.
; mail(), ereg(), etc are overloaded by mb_send_mail(), mb_ereg(),
; etc. Possible values are 0,1,2,4 or combination of them.
; For example, 7 for overload everything.
; 0: No overload
; 1: Overload mail() function
; 2: Overload str*() functions
; 4: Overload ereg*() functions
; http://php.net/mbstring.func-overload
;mbstring.func_overload = 0
; enable strict encoding detection.
; Default: Off
;mbstring.strict_detection = On
; This directive specifies the regex pattern of content types for which mb_output_handler()
; is activated.
; Default: mbstring.http_output_conv_mimetype=^(text/|application/xhtml\+xml)
;mbstring.http_output_conv_mimetype=
[gd]
; Tell the jpeg decode to ignore warnings and try to create
; a gd image. The warning will then be displayed as notices
; disabled by default
; http://php.net/gd.jpeg-ignore-warning
;gd.jpeg_ignore_warning = 0
[exif]
; Exif UNICODE user comments are handled as UCS-2BE/UCS-2LE and JIS as JIS.
; With mbstring support this will automatically be converted into the encoding
; given by corresponding encode setting. When empty mbstring.internal_encoding
; is used. For the decode settings you can distinguish between motorola and
; intel byte order. A decode setting cannot be empty.
; http://php.net/exif.encode-unicode
;exif.encode_unicode = ISO-8859-15
; http://php.net/exif.decode-unicode-motorola
;exif.decode_unicode_motorola = UCS-2BE
; http://php.net/exif.decode-unicode-intel
;exif.decode_unicode_intel = UCS-2LE
; http://php.net/exif.encode-jis
;exif.encode_jis =
; http://php.net/exif.decode-jis-motorola
;exif.decode_jis_motorola = JIS
; http://php.net/exif.decode-jis-intel
;exif.decode_jis_intel = JIS
[Tidy]
; The path to a default tidy configuration file to use when using tidy
; http://php.net/tidy.default-config
;tidy.default_config = /usr/local/lib/php/default.tcfg
; Should tidy clean and repair output automatically?
; WARNING: Do not use this option if you are generating non-html content
; such as dynamic images
; http://php.net/tidy.clean-output
tidy.clean_output = Off
[soap]
; Enables or disables WSDL caching feature.
; http://php.net/soap.wsdl-cache-enabled
soap.wsdl_cache_enabled=1
; Sets the directory name where SOAP extension will put cache files.
; http://php.net/soap.wsdl-cache-dir
soap.wsdl_cache_dir="/tmp"
; (time to live) Sets the number of second while cached file will be used
; instead of original one.
; http://php.net/soap.wsdl-cache-ttl
soap.wsdl_cache_ttl=86400
; Sets the size of the cache limit. (Max. number of WSDL files to cache)
soap.wsdl_cache_limit = 5
[sysvshm]
; A default size of the shared memory segment
;sysvshm.init_mem = 10000
[ldap]
; Sets the maximum number of open links or -1 for unlimited.
ldap.max_links = -1
[mcrypt]
; For more information about mcrypt settings see http://php.net/mcrypt-module-open
; Directory where to load mcrypt algorithms
; Default: Compiled in into libmcrypt (usually /usr/local/lib/libmcrypt)
;mcrypt.algorithms_dir=
; Directory where to load mcrypt modes
; Default: Compiled in into libmcrypt (usually /usr/local/lib/libmcrypt)
;mcrypt.modes_dir=
[dba]
;dba.default_handler=
[opcache]
; Determines if Zend OPCache is enabled
opcache.enable=1
; Determines if Zend OPCache is enabled for the CLI version of PHP
opcache.enable_cli=1
; The OPcache shared memory storage size.
opcache.memory_consumption=128
; The amount of memory for interned strings in Mbytes.
opcache.interned_strings_buffer=8
; The maximum number of keys (scripts) in the OPcache hash table.
; Only numbers between 200 and 100000 are allowed.
opcache.max_accelerated_files=4000
; The maximum percentage of "wasted" memory until a restart is scheduled.
;opcache.max_wasted_percentage=5
; When this directive is enabled, the OPcache appends the current working
; directory to the script key, thus eliminating possible collisions between
; files with the same name (basename). Disabling the directive improves
; performance, but may break existing applications.
;opcache.use_cwd=1
; When disabled, you must reset the OPcache manually or restart the
; webserver for changes to the filesystem to take effect.
;opcache.validate_timestamps=1
; How often (in seconds) to check file timestamps for changes to the shared
; memory storage allocation. ("1" means validate once per second, but only
; once per request. "0" means always validate)
;opcache.revalidate_freq=2
; Enables or disables file search in include_path optimization
;opcache.revalidate_path=0
; If disabled, all PHPDoc comments are dropped from the code to reduce the
; size of the optimized code.
;opcache.save_comments=1
; If enabled, a fast shutdown sequence is used for the accelerated code
; Depending on the used Memory Manager this may cause some incompatibilities.
;opcache.fast_shutdown=0
; Allow file existence override (file_exists, etc.) performance feature.
;opcache.enable_file_override=0
; A bitmask, where each bit enables or disables the appropriate OPcache
; passes
;opcache.optimization_level=0xffffffff
;opcache.inherited_hack=1
;opcache.dups_fix=0
; The location of the OPcache blacklist file (wildcards allowed).
; Each OPcache blacklist file is a text file that holds the names of files
; that should not be accelerated. The file format is to add each filename
; to a new line. The filename may be a full path or just a file prefix
; (i.e., /var/www/x blacklists all the files and directories in /var/www
; that start with 'x'). Line starting with a ; are ignored (comments).
;opcache.blacklist_filename=
; Allows exclusion of large files from being cached. By default all files
; are cached.
;opcache.max_file_size=0
; Check the cache checksum each N requests.
; The default value of "0" means that the checks are disabled.
;opcache.consistency_checks=0
; How long to wait (in seconds) for a scheduled restart to begin if the cache
; is not being accessed.
;opcache.force_restart_timeout=180
; OPcache error_log file name. Empty string assumes "stderr".
;opcache.error_log=
; All OPcache errors go to the Web server log.
; By default, only fatal errors (level 0) or errors (level 1) are logged.
; You can also enable warnings (level 2), info messages (level 3) or
; debug messages (level 4).
;opcache.log_verbosity_level=1
; Preferred Shared Memory back-end. Leave empty and let the system decide.
;opcache.preferred_memory_model=
; Protect the shared memory from unexpected writing during script execution.
; Useful for internal debugging only.
;opcache.protect_memory=0
; Allows calling OPcache API functions only from PHP scripts which path is
; started from specified string. The default "" means no restriction
;opcache.restrict_api=
; Mapping base of shared memory segments (for Windows only). All the PHP
; processes have to map shared memory into the same address space. This
; directive allows to manually fix the "Unable to reattach to base address"
; errors.
;opcache.mmap_base=
; Enables and sets the second level cache directory.
; It should improve performance when SHM memory is full, at server restart or
; SHM reset. The default "" disables file based caching.
;opcache.file_cache=
; Enables or disables opcode caching in shared memory.
;opcache.file_cache_only=0
; Enables or disables checksum validation when script loaded from file cache.
;opcache.file_cache_consistency_checks=1
; Implies opcache.file_cache_only=1 for a certain process that failed to
; reattach to the shared memory (for Windows only). Explicitly enabled file
; cache is required.
;opcache.file_cache_fallback=1
; Enables or disables copying of PHP code (text segment) into HUGE PAGES.
; This should improve performance, but requires appropriate OS configuration.
opcache.huge_code_pages=1
; Validate cached file permissions.
; opcache.validate_permission=0
; Prevent name collisions in chroot'ed environment.
; opcache.validate_root=0
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
;curl.cainfo =
[openssl]
; The location of a Certificate Authority (CA) file on the local filesystem
; to use when verifying the identity of SSL/TLS peers. Most users should
; not specify a value for this directive as PHP will attempt to use the
; OS-managed cert stores in its absence. If specified, this value may still
; be overridden on a per-stream basis via the "cafile" SSL stream context
; option.
;openssl.cafile=
; If openssl.cafile is not specified or if the CA file is not found, the
; directory pointed to by openssl.capath is searched for a suitable
; certificate. This value must be a correctly hashed certificate directory.
; Most users should not specify a value for this directive as PHP will
; attempt to use the OS-managed cert stores in its absence. If specified,
; this value may still be overridden on a per-stream basis via the "capath"
; SSL stream context option.
;openssl.capath=
[apcu]
apc.shm_size=1024M
apc.slam_defense=1
apc.serializer=igbinary
[memcached]
memcached.sess_connect_timeout=1000
memcached.sess_consistent_hash=0
memcached.sess_lock_max_wait=0
memcached.sess_lock_wait=150000
memcached.sess_binary_protocol = 0
memcached.sess_prefix = memc.sess.key
[yaconf]
yaconf.directory=/home/services/api.go2yd.com/htdocs/Website/yaconf
; Local Variables:
; tab-width: 4
; End:
#!/bin/bash
cd /home/services/api.go2yd.com/htdocs/Website/data && wget http://10.103.17.28/ipip/ipdata_ipv6v4_2in1.ipdb.zip && unzip -o ipdata_ipv6v4_2in1.ipdb.zip && rm -f ipdata_ipv6v4_2in1.ipdb.zip && cd -
/home/services/api.go2yd.com/logs/*.log {
su root root
daily
dateext
rotate 7
missingok
notifempty
create 755 nobody nobody
postrotate
/bin/kill -SIGUSR1 `cat /var/run/php-fpm/php-fpm.pid 2>/dev/null` 2>/dev/null || true
endscript
}
#!/bin/sh
/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0
;;;;;;;;;;;;;;;;;;;;;
; FPM Configuration ;
;;;;;;;;;;;;;;;;;;;;;
; All relative paths in this configuration file are relative to PHP's install
; prefix.
; Include one or more files. If glob(3) exists, it is used to include a bunch of
; files from a glob(3) pattern. This directive can be used everywhere in the
; file.
include=/etc/php-fpm.d/*.conf
;;;;;;;;;;;;;;;;;;
; Global Options ;
;;;;;;;;;;;;;;;;;;
[global]
; Pid file
; Default Value: none
pid = /var/run/php-fpm/php-fpm.pid
; Error log file
; Default Value: /var/log/php-fpm.log
; error_log = syslog
; syslog.facility = local7
; syslog.ident = php-fpm
error_log = /home/services/api.go2yd.com/logs/fpm-error.log
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
log_level = warning
; If this number of child processes exit with SIGSEGV or SIGBUS within the time
; interval set by emergency_restart_interval then FPM will restart. A value
; of '0' means 'Off'.
; Default Value: 0
;emergency_restart_threshold = 0
; Interval of time used by emergency_restart_interval to determine when
; a graceful restart will be initiated. This can be useful to work around
; accidental corruptions in an accelerator's shared memory.
; Available Units: s(econds), m(inutes), h(ours), or d(ays)
; Default Unit: seconds
; Default Value: 0
;emergency_restart_interval = 0
; Time limit for child processes to wait for a reaction on signals from master.
; Available units: s(econds), m(inutes), h(ours), or d(ays)
; Default Unit: seconds
; Default Value: 0
process_control_timeout = 7
; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging.
; Default Value: yes
daemonize = yes
;;;;;;;;;;;;;;;;;;;;
; Pool Definitions ;
;;;;;;;;;;;;;;;;;;;;
; See /etc/php-fpm.d/*.conf
# 说明: 本脚本为docker的启动脚本, 执行此脚本请传入2个参数
# 参数个数为3: $1->环境, $2->端口 $3->域名前缀(metro-test.go2yd.com)
# 环境:外网两个环境 内网两个环境 内网环境且不对外test_internal
# 外网环境 prod/perf/test
# 内网环境 prod_internal/perf_internal/test_internal
if [ $# -lt 3 ]; then
echo "env cannot empty"
exit -1
fi
environment=${1}
port=${2}
domain_prefix=${3}
#运行时配置内核参数
sysctl -w net.core.somaxconn=65535 net.ipv4.ip_local_port_range='1024 65530' vm.nr_hugepages=512
#close transparent_hugepage 是否启用透明大页[never]表示透明大页禁用
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
#start_script.done is the mark when service start
rm -f /home/services/api.go2yd.com/logs/start_script.done
#load the config file
if [ ! -d "/etc/php-fpm.d/" ]; then
mkdir /etc/php-fpm.d/
fi
if [ ! -d "/var/run/php-fpm/" ]; then
mkdir /var/run/php-fpm/
fi
\cp -f /home/services/api.go2yd.com/htdocs/Website/deploy/start_env/php-fpm.conf /etc/php-fpm.conf
\cp -f /home/services/api.go2yd.com/htdocs/Website/deploy/start_env/api.go2yd.com.conf /etc/php-fpm.d/api.go2yd.com.conf
# 宿主机ip不一定为172.17.0.1
# -z string长度是否为0
if [ -z "${YIDIAN_LOCAL_IP}" ]; then
printf "\nenv[YIDIAN_LOCAL_IP]=172.17.0.1\n" >> /etc/php-fpm.d/api.go2yd.com.conf
else
printf "\nenv[YIDIAN_LOCAL_IP]=%s\n" "${YIDIAN_LOCAL_IP}" >> /etc/php-fpm.d/api.go2yd.com.conf
fi
#php.ini要根据环境去修改
if [[ X"${environment}" == X"prod" || X"${environment}" == X"prod_internal" ]];then
sed -i "s#yaf.environ=dev#yaf.environ=prod#g" ini/php.ini
elif [[ X"${environment}" == X"perf" || X"${environment}" == X"perf_internal" ]];then
sed -i "s#yaf.environ=dev#yaf.environ=perf#g" ini/php.ini
elif [[ X"${environment}" == X"test" || X"${environment}" == X"test_internal" ]];then
sed -i "s#yaf.environ=dev#yaf.environ=test#g" ini/php.ini
fi
# choose the php ini file for different env
\cp -f ini/php.ini /etc/php.ini
if [ -e "/usr/share/zoneinfo/Asia/Shanghai" ];then
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
fi
#code collect coverage for FT
if [ "$collect_coverage" = "true" ]; then
sh /home/services/collect_coverage/start_collect_coverage.sh
fi
#set the pool of php-fpm
sed -i "/^\[.*\]$/s#api#${domain_prefix}#g" /etc/php-fpm.d/api.go2yd.com.conf
#rsyslogd启动日志 系统中的绝大多数日志文件是由 rsyslogd 服务来统一管理的只要各个进程将信息给予这个服务,它就会自动地把日志按照特定的格式记录到不同的日志文件中。也就是说,采用 rsyslogd 服务管理的日志文件,它们的格式应该是统一的。
rsyslogd > /dev/null 2>&1
cp -f /home/services/logrotate.conf /etc/logrotate.d/php-fpm
mv /etc/anacrontab /etc/anacrontab.bak # 取消系统调度logrotate,采用自定义的crontab时间执行
#crontab
nohup /usr/sbin/crond >crond.nohup &
crontab /home/services/crontab.conf
#create the log file, fix dir permissions
if [ ! -d "/etc/php-fpm.d/" ]; then
mkdir /home/services/api.go2yd.com/logs/
fi
if [ ! -f "/home/services/api.go2yd.com/logs/php-error.log" ];then
touch /home/services/api.go2yd.com/logs/php-error.log
fi
if [ ! -f "/home/services/api.go2yd.com/logs/access.log" ];then
touch /home/services/api.go2yd.com/logs/access.log
fi
if [ ! -f "/home/services/api.go2yd.com/logs/fpm-error.log" ];then
touch /home/services/api.go2yd.com/logs/fpm-error.log
fi
if [ ! -f "/home/services/api.go2yd.com/logs/fpm-slow.log" ];then
touch /home/services/api.go2yd.com/logs/fpm-slow.log
fi
chmod -R 777 /home/services/api.go2yd.com/logs
chown -R nobody:nobody /home/services/api.go2yd.com/logs
#add apc.php to the web root
#可选PHP缓存 APC的缓存分两部分:系统缓存和用户数据缓存
cp -f /home/services/api.go2yd.com/htdocs/Website/deploy/start_env/apc.php /home/services/api.go2yd.com/htdocs/Website/debug/apc.php
# 线上需要删除这个标记的方法if not for internal use, remove flagged codes
if [[ X"${environment}" != X"test_internal" && X"${environment}" != X"prod_internal" ]];then
grep -l '@mark FOR_INTERNAL_USE_ONLY' /home/services/api.go2yd.com/htdocs/Website/*/*/*/*/* | xargs rm
fi
#  日志
sed -i "s/service_name: 'api.go2yd.com'/service_name: '${domain_prefix}.go2yd.com'/g" filebeat-log.yml
# filebeat start
chmod go-w /home/services/filebeat-log.yml
nohup /filebeat-6.3.1-linux-x86_64/filebeat -c /home/services/filebeat-log.yml &
while true; do
nohup /usr/sbin/php-fpm -F &
fpm_pid=$!
sleep 5
#docker stop优雅关闭php-fpm
trap "kill -3 $fpm_pid;exit 0" 15
# 检测php-fpm是否启动成功 端口9000是容器内固定的值
sh api_checker/api_checker.sh 9000 {$domain_prefix}
if [ "$?" != 0 ]; then
if [ ! -f /home/services/api.go2yd.com/logs/start_script.done ]; then
exit 2
else
kill $fpm_pid
sleep 10
fi
else
touch /home/services/api.go2yd.com/logs/start_script.done
fi
wait $fpm_pid
exit 3
done;
\ No newline at end of file
## protobuf
#### protobuf3 的定义文件在yaconf中统一管理
\ No newline at end of file
<?php
ini_set("display_errors", "On");//打开错误提示
ini_set("error_reporting",E_ALL);//显示所有错误
/*
* cli入口脚本
* cli 配置文件:conf/cli.ini
* cli bootstrap:application/BootstrapCli.php ( 在cli.ini中配置
* 默认模块:modules/cli
* 脚本位置:modules/cli/controllers/xxx.php
* 调用方式:php cli.php controller action "a=1&b=2"
* 测试脚本:php cli.php test index "a=1&b=2"
*/
if( !substr(php_sapi_name(), 0, 3) == 'cli' ) {
die;
}
define('APPLICATION_PATH', realpath(__DIR__.'/../'));
require APPLICATION_PATH . '/vendor/autoload.php';
$application = new Yaf\Application( APPLICATION_PATH . "/conf/cli.ini");
/**
* 获取模块/控制器/方法
*/
$module = "cli";
$controller = $argv[1] ?? "";
$method = $argv[2] ?? "";
$param = $argv[3] ?? [];
if ($param)
{
$param = convertUrlQuery($param);
}
$application->bootstrap()->getDispatcher()->dispatch( new Yaf\Request\Simple("", $module, $controller,$method,$param) );
function convertUrlQuery($query)
{
$queryParts = explode('&', $query);
$params = array();
foreach ($queryParts as $param) {
$item = explode('=', $param);
$params[$item[0]] = $item[1];
}
return $params;
}
\ No newline at end of file
<?php
ini_set("display_errors", "On");
/* 定义这个常量是为了在application.ini中引用*/
define('ROOT_PATH', realpath(__DIR__.'/../'));
define('APP_PATH', realpath(__DIR__.'/../application'));
define('APP_START', microtime(true));
// 调试参数 __debug 的值
define('_DEBUG_PASS', 'debugpass'); // 为了避免调试信息泄漏,请定义自己的密钥
// 是否开启调试状态
define('_IS_DEBUG', true);
// 异常信息等级
define('_ERROR_LEVEL', E_ALL);
$application = new Yaf\Application( ROOT_PATH . "/conf/application.ini");
$application->bootstrap()->run();
<?php
echo "success";
\ No newline at end of file
<?php
function delgit($dir)
{
$dh = opendir($dir);
//找出所有".git" 的文件夹:
while ($file = readdir($dh)) {
if ($file != "." && $file != "..") {
$fullpath = $dir . "/" . $file;
if (is_dir($fullpath)) {
if ($file == ".git") {
delgitdir($fullpath);
} else {
delgit($fullpath);
}
}
}
}
closedir($dh);
}
function delgitdir($gitdir)
{
//先删除目录下的文件:
$dh = opendir($gitdir);
while ($file = readdir($dh)) {
if ($file != "." && $file != "..") {
$fullpath = $gitdir . "/" . $file;
if (is_dir($fullpath)) {
delgitdir($fullpath);
} else {
unlink($fullpath);
}
}
}
closedir($dh);
//删除目录文件夹
if (rmdir($gitdir)) {
return true;
} else {
return false;
}
}
$dir = __DIR__. '/vendor/api';
delgit($dir);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment