php系统日志切割的实例
我习惯设置的日志路径是这样
/home/www/logs/域名.log
比如
/home/www/logs/www.yundaiwei.com.log
为了方便管理,日志需要按天保存在一个文件中,并且保留指定天数的日志,超过时间的就删除。
分享一下脚本
#!/usr/bin/php
<?php
$logdir = '/home/www/logs/';
// 保留天数含当天
$log_save_day = 7;
$files = glob("{$logdir}/*");
foreach($files as $path){
$filename = basename($path);
preg_match("/(\d{8})\.log/", $filename, $preg);
$date = @$preg[1];
if(empty($date)){
// 当天日志,更改文件名
$newpath = $logdir . '/' . str_replace('log', date('Ymd',strtotime("-1 day")).'.log', $filename);
rename($path, $newpath);
echo "$path >>> $newpath\n";
}else{
// 超过保留天数,删除
if(time()+10 - strtotime($date) > 3600*24*$log_save_day){
unlink($path);
echo "$path delete!\n";
}
}
}
shell_exec('/etc/init.d/nginx reload &> /dev/null');
PHP curl实现多进程并发抓取数据我们经常的用到了,今天我们来看一篇关于PHP curl实现多进程并发高效率采集爬虫的例子,具体的细节如下。演示代码
运行效果(图1)
运行效果(图2)
主要封装函数
multi_process();
根据参数,创建指点数目的子进程。
亮点功能1:子进程各种异常退出,比如segment fault, Allowed memory size exhausted等,中断一个子进程后,父进程会重新fork一个新进程顶上去,保持子进程数量。如果子进程里完成任务(比如判断tid达到10000),可以在子进程里exit(9),父进程会收到这个退出状态(9),然后等待所有子进程退出,最后退出自身进程。
亮点功能2:与curl封装函数一起实现了一统计功能,在程序关闭后会显示出一些主要的统计信息(图2的底部)。
mp_counter();
在父进程以及所有子进程之间通信,负责协调分配各子进程的任务,使用了锁机制。可以设置’init’参数重置计数,可以设置每次更新计数的值。
curl_get();
对curl相关函数的封装,加入了大量的错误机制,支持POST,GET,Cookie,Proxy,下载。
mp_msg();
实现规范之一就是,每条任务处理完,只输出一行信息。
亮点功能:这个函数会判断终端的高度和宽度,实现每一屏内容会显示一条统计信息(图1的紫色行),便于观察程序的执行情况,控制每一行输出的长度,保持一条信息不会超过一行。
rand_exit();
众所周知,PHP存在内在泄露的问题,所以每一个子进程里执行一定次数的任务后就退出,由multi_process()负责自动建立新的子进程(如图1中的绿色行)。
程序效率
本次测试使用的是Vultr的最低配置机器,1 CPU(3.6GHz),768MB RAM,美国LA机房(一定程度上影响了抓取速度)。
执行了十多分钟后,统计信息如下:
运行期间内存占用统计(while true; do psmem | grep php;sleep 10; done)如下:
vmstat 1命令结果如下
iftop带宽监控如下:
50个子进程,执行11分55秒,抓取50951次,按这个速度计算,一天可以抓取615万次。
所有进程(1父进程+50子进程)共占用内存约60MB,占用CPU约20%(1核心),带宽占用约7-8Mbps。
不同进程数量的抓取速度对比:
1个进程
100个进程
多进程的封装几乎完美,但curl由于它的功能太过于丰富和强大,可能永远也无法达到完美
代码如下
curl.lib.php
代码如下 | 复制代码 |
<?php // 命令行颜色输出 /* /* /* /* // cookie和临时文件目录 // 清除过期的cookie文件和下载临时文件 /** /** /** if(!$header_text){ // 处理状态码 /** return curl_func($url, $method, $data, $path, $proxy); /**
/** function img_down($url, $path_pre){ function get_img_ext($path){ /** } /** /** /** /** // 控制台输出颜色 // 去除URL中的/../ // 去除实体转码 // 统计数据 for($i = 0; $i < curl_config_get('retry'); $i++){ // 初始化 // 设置超时 // 接收网页内容到变量 // 忽略SSL验证 // 设置referer, 在文件里配置的优先级最高 // 设置HTTP请求标识,在文件里配置的优先级最高 curl_setopt($ch, CURLOPT_USERAGENT, $useragent); // 出口IP // 设置代理 // 设置允许接收gzip压缩数据,以及解压,抓取HEADER时不使用(获取不到正确的文件大小,影响判断下载成功) // 遇到301和302转向自动跳转继续抓取,如果用于WEB程序并且设置了open_basedir,这个选项无效 // 启用cookie // 设置post参数内容 // 设置用于下载的参数 // 仅获取header // 抓取结果 // 调试curl时间,记录连接时间,等待时间,传输时间,总时间。 // 关闭CURL句柄 // 如果CURL有错误信息则判断为抓取失败,重试 // 统计流量 // 对结果进行处理 if(in_array($status_code, array_merge(range(400, 417), array(500, 444)))){ if(empty($savepath)){ // 分析页面编码 // 转码条件:1)匹配到编码, 2)返回编码不为空, 3)匹配到的编码和返回编码不相同 // iconv如果失败则返回空白页 // 统计下载文件量 return TRUE; // 如果是下载或者抓取header,并且错误代码为6(域名无法解析),则不输出错误。失效的图片引用太多了。 // 统计数据 return FALSE; /** // 多并发下建议关闭黄色错误输出 if(php_sapi_name() != 'cli'){ if(!in_array($color, $available_msg)){ echo "{$reverse}".$colors[$color]."({$method})[cURL ERROR: {$msg}] {$url}{$end}\n"; /** /** function relative_to_absolute($content, $url) { preg_match("/(http|https|ftp):\/\/[^\/]*/", $url, $preg_base); preg_match("/(http|https|ftp):\/\/.*\//", $url, $preg_full); return $content; /** $cookie_files = glob("{$cookie_dir}curl_*_pid_*"); foreach($files as $file){
}
function curl_rand_ua_pc(){ function curl_rand_ua_mobile(){ function curl_config_get($key){ if(!empty($curl_config[getmypid()][$key])){ function curl_config_set($key, $val){ function curl_set_ua($ua){ function curl_set_referer($referer){ function curl_set_retry($retry){ function curl_set_conntimeout($conntimeout){ function curl_set_fetchtimeout($fetchtimeout){ function curl_set_downtimeout($downtimeout){ |
process.lib.php
代码如下 | 复制代码 |
<?php declare(ticks = 1); // 中断信号 // 命令行颜色输出 // 程序开始运行时间 // 父进程PID // 文件保存目录,/dev/shm/是内存空间映射到硬盘上,IO速度快。 // 清理过期资源(文件和SEM信号锁),每次程序执行都需要调用,清除掉之前执行时的残留文件。 // 判断是否在子进程中 /** // 父进程PID或者自身PID // 系统启动时间 // 进程启动时间 // 由父进程ID确定变量文件路径前缀 // 由于系统启动时间和当前父进程启动时间(jiffies格式)确定计数使用的文件 // 更新计数,先锁定 if(!file_exists($cur_path)){ $counter = 0; // 更新记数, 继续研究下判断init不能用== // 写入计数,解锁 return $new_counter; /** if(empty($num)){ // 记录进程数量,统计用 // 子进程数量 // 任务完成标识 while(TRUE) { // 清空子进程退出状态 // 如果任务未完成,并且子进程数量没有达到最高,则创建 // 注册父进程的信号处理函数 //$stat && pcntl_signal(SIGINT, "signal_handler"); echo "{$reverse}{$green}[+]New Process Forked: {$pid}{$end}\n"; // 1,注册一个信号,处理函数直接exit(),目的是让子进程不进行任何处理,仅由主进程处理这个信号 // 注册信号后直接返回,继续处理主程序的后续部分。 // 子进程管理部分 // 统计信息 // 子进程退出状态码为9时,则判断为所有任务完成,然后等待所有子进程退出
if(strpos($script, '/') === FALSE || strpos($script, '..') !== FALSE){ return $path; function final_stat(){ // 时间统计 // curl抓取统计 $down_total = mp_counter('down_total', 0); $header_total = mp_counter('header_total', 0); $download_size = hs(mp_counter('download_size', 0)); echo " Request Stat: Fetch({$fetch_success}/{$fetch_total}), Header({$header_success}/{$header_total}), "; // curl流量统计 // 效率统计 echo "========================================================================{$end}\n"; /** function sub_process_exit(){ function hnum($num){ /**
/** if(!function_exists('get_ppid')){ // 以进程(多进程运行时,使用父进程)为单位,每个进程使用一个锁。 // 解除锁 // 清理资源(文件和SEM信号锁) // 清除sem的文件和信号量 // 清除mp_counter的文件(仅此类型文件不可重用,所以严格处理,匹配系统启动时间和进程启动时间) // 清除文件 // 系统启动时间 // 如果是在子进程中调用,则取父进程的启动时间。如果不是在子进程中调用,则取自身启动时间。时间都是jiffies格式。 // 防止PHP进程内存泄露,每个子进程执行完一定数量的任务就退出。 // 单次的任务结果输出函数 // 整理统计信息 // cron方式运行 $lock = sem_lock('mp_msg'); $t_cols = mp_counter('t_cols', 0); if($t_lines <= 1){ $process_num = mp_counter('process_num', 0); $fetch_total = mp_counter('fetch_total', 0); echo "{$reverse}{$purple}"; } |
Composer是PHP的一个依赖管理工具,它使得PHP焕发新的生机,有了现代化的WEB开发规范,Packagist是PHP组件的库,也有其他的镜像。
在Packagist上提交了一个自己开发的PHP组件,这样其他开发者就可以使用Composer使用这个包了。这个组件并没什么功能,主要是看看提交PHP组件的流程,并记录了过程中遇到的问题及解决方法,以供参考。
提交PHP组件步骤:
1.新建一个项目目录,创建一个composer.json文件,格式如下:
PHP
{
"name": "your-vendor-name/package-name",
"description": "A short description of what your package does",
"require": {
"php": "^5.3.3 || ^7.0",
"another-vendor/package": "1.*"
}
}
这个json格式的文件中包含组件的基本信息,这里还差自动加载的方式,要根据具体开发模式指定自动加载方式,这里require可以指定这个组件依赖的其他组件,composer都会自动解决依赖。
附上完整的composer.json内容作为示例:
JavaScript
{
"name": "tanteng/laravel-page-loaded-time",
"description": "Display page loaded time",
"keywords": ["laravel","performance"],
"homepage": "https://github.com/tanteng/laravel-page-loaded-time",
"license": "MIT",
"authors": [
{
"name": "tanteng",
"email": "tanteng@qq.com",
"homepage": "http://www.tanteng.me",
"role": "Developer"
}
],
"require": {
"php": "^5.3.3 || ^7.0",
"laravel/framework": "~4.0"
},
"autoload": {
"psr-4": { "Loading\\": "" }
}
}
2.开发组件功能
要注意遵循psr规范,使用命名空间。
3.把组件提交到Github上
提交组件到Packagist之前需要先把代码提交到github上,在Packagist只需填写组件的github地址。
4.提交组件地址到Packagist
这样就完成的PHP组件提交到Packagist的过程,具体请参见Packagist官网。
问题:使用composer require找不到组件
组件提交到Packagist上,提示发布成功了,但是使用composer命令却找不到组件:
PHP
composer require tanteng/laravel-page-loaded-time
如图:
由于我的composer使用的国内镜像,猜测可能是没有同步的原因,使用这个命令把“源”改回去还是不行。
PHP
composer config -g repo.packagist composer https://packagist.org
原来我的组件还没有在github上发布正式,这个时候还是开发版本dev-master.应该加上dev-master版本。
PHP
composer require tanteng/laravel-page-loaded-time:dev-master
果然指定了dev-master版本可以成功更新组件,但是这样不行,我们要有一个正式版本。
github发布版本
进入组件的github主页,找到导航上“releases”,点击进去如图页面,就可以创建一个版本,填写好信息之后即可发布版本。
按照页面上的提示填写内容,完成后发布。发布版本后,通过composer require发现还是找不到包。
设置自动更新版本
原来还要在Github上配置一下自动更新。具体步骤参考:https://packagist.org/about#how-to-update-packages
我直接通过手动的方式发送curl请求来设置,这样还简单一点,不过这样每次发新的版本都需要这样请求一下:
PHP
curl -XPOST -H'content-type:application/json' 'https://packagist.org/api/update-package?username=tanteng&apiToken=secret' -d'{"repository":{"url":"https://github.com/tanteng/laravel-page-loaded-time"}}'
返回{“status”:”success”}表示成功。
再打开https://packagist.org/packages/tanteng/laravel-page-loaded-time,发现已经是正式版本了。
我用的是composer国内镜像,因为众所周知的原因,连代码仓库也要被墙,我服!等了几个小时再试,这个时候镜像同步更新了,再次输入:composer require tanteng/laravel-page-loaded-time,这个时候可以成功更新了。如图,vendor文件夹下也自动装载了依赖的其他组件
命名规则其实还是有一点的要求会比较好,否则不统计也难看了,下面整理了一篇关于PHP变量命名规则详解,希望下面的文章对各位有用。PHP变量命名规则
1、变量以美元符号$开头。如$name,$age。
2、美元符号$后面的第一个字符不可以是数字,只能是下划线_或者字母。如$1_1这样的变量是错误的。
3、除了下划线_外,变量不允许出现任何空格或标点符号。也就是说变量名只能包含:a-z、A-Z、0-9 以及下划线_。
4、PHP变量名是区分大小写的。如$name与$Name是两个不同的变量。
PHP变量命名规则其余注意事项
1、当用两个或两个以上的单词命名变量时,可以将除第一个单词以外的所有单词的首字母大写。如$myName、$yourFamilyName。
2、以下划线_开始命名的变量通常代表特殊的变量。如在类中创建受保护的属性、PHP预定义变量($_GET)、全局数组等。
3、定义变量的时候,不要贪图简短,而应该使用具有描述性的名称定义变量。
学而不思则罔,思而不学则殆。希望您在学习PHP的道路上一帆风顺,并成为PHP编程艺术大师。
以上便是PHP变量命名规则的全部内容。以下是废话,如果您有时间,不妨粗略阅读,也许您能产生共鸣。
PHP变量命名规则
从大学开始到现在,陆陆续续接触过各种编程语言。如客户端语言Javascript,Actionscript;服务器端语言C++,Java,ASP.net,PHP等等,不一而足。在所有这些语言中,我最想学的是PHP。不为别的,就因为PHP的读法:屁H屁,说起来琅琅上口,韵味十足。今天看到PHP变量命名规则这一节,索性就随便写一点东西,聊以打发无聊的光阴。
对PHP的学习,一直时断时续。年轻时候要学好PHP的雄心壮志如今差不多荡然无存了。
有人说,活在这样一个社会里,没有人能一尘不染地活着。这是个怎样的社会?我不太清楚。不过我听人说,这是个聋子听见哑巴说瞎子看见了爱情的扯淡时代。不完全信,但也无法完全不信。
不管怎样,既然活着是不容易的,那么就且活且珍惜吧。
PHP是我想珍惜的。
于是,今天翻了一翻从图书馆借来的新书——PHP动态网页设计(第二版,作者David Powers)。
看到PHP变量命名规则一节。这些非常基础的内容,在时隔数年之后重新温习,倒是真有温故而知新的感觉。
为了使印象更为深刻,也为了实践,好记性不如烂笔头的真理,在这不太安分的夜里,我决定写这篇文章,献给曾经想成为PHP高手的自己。
1、变量以美元符号$开头。如$name,$age;
2、美元符号$后面的第一个字符不可以是数字;
3、除了下划线_外,变量不允许出现任何空格或者标点符号;
4、PHP变量名是区分大小写的。如$name与$Name是两个不同的变量。
其余注意事项
1、当用两个或两个以上的单词命名变量时,可以将除第一个单词以外的所有单词的首字母大写。如$myName;$yourFamilyName;
2、以下划线_开始命名的变量通常留给特殊的情况使用。如在类中创建受保护的属性;PHP预定义变量:全局数组等;
3、定义变量的时候,不要贪图简短,而应该使用具有描述性的名称定义变量。
例子
面是分别用骆驼式命名法和下划线法命名的同一个函数:
printEmployeePaychecks();
print_employee_paychecks();
第一个函数名使用了骆驼式命名法——函数名中的每一个逻辑断点都有一个大写字母来标记;第二个函数名使用了下划线法----函数名中的每一个逻辑断点都有一个下划线来标记。
骆驼式命名法近年来越来越流行了,在许多新的函数库和Microsoft Windows这样的环境中,它使用得相当多。另一方面,下划线法是c出现后开始流行起来的,在许多旧的程序和UNIX这样的环境中,它的使用非常普遍。
编辑本段应用概述
骆驼式命名法(Camel-Case)是电脑程式编写时的一套命名规则(惯例)。
骆驼式命名法就是当变量名或函式名是由一个或多个单字连结在一起,而构成的唯一识别字时,第一个单词以小写字母开始;第二个单词的首字母大写或每一个单词的首字母都采用大写字母,例如:myFirstName、myLastName,这样的变量名看上去就像骆驼峰一样此起彼伏,故得名。
骆驼式命名法(Camel-Case)一词来自 Perl 语言中普遍使用的大小写混合格式,而 Larry Wall 等人所著的畅销书《Programming Perl》(O'Reilly 出版)的封面图片正是一匹骆驼。
骆驼式命名法的命名规则可视为一种惯例,并无绝对与强制,为的是增加识别和可读性。
驼峰法(小驼峰法)
变量一般用小驼峰法标识。驼峰法的意思是:除第一个单词之外,其他单词首字母大写。譬如
int myStudentCount;
变量myStudentCount第一个单词是全部小写,后面的单词首字母大写。
Pascal法(大驼峰法)
相比小驼峰法,大驼峰法把第一个单词的首字母也大写了。常用于类名,函数名,属性,命名空间。譬如
publicclass DataBaseUser;
堆排序
堆排序是利用堆的性质进行的一种选择排序。下面先讨论一下堆。
1.堆
堆实际上是一棵完全二叉树,其任何一非叶节点满足性质:
Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]或者Key[i]>=Key[2i+1]&&key>=key[2i+2]
即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字。
堆分为大顶堆和小顶堆,满足Key[i]>=Key[2i+1]&&key>=key[2i+2]称为大顶堆,满足 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]称为小顶堆。由上述性质可知大顶堆的堆顶的关键字肯定是所有关键字中最大的,小顶堆的堆顶的关键字是所有关键字中最小的。
2.堆排序的思想
利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单。
其基本思想为(大顶堆):
1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无须区;
2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];
3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
操作过程如下:
1)初始化堆:将R[1..n]构造为堆;
2)将当前无序区的堆顶元素R[1]同该区间的最后一个记录交换,然后将新的无序区调整为新的堆。
因此对于堆排序,最重要的两个操作就是构造初始堆和调整堆,其实构造初始堆事实上也是调整堆的过程,只不过构造初始堆是对所有的非叶节点都进行调整。
堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法。学习堆排序前,先讲解下什么是数据结构中的二叉堆。
PHP 堆管理代码如下:
代码如下 | 复制代码 |
<?php $arr = [10,40,30]; heep::add($arr,40); echo join(',',$arr),'<br>'; heep::del($arr); heep::sort($arr); $arr = [40,10,30]; |
假设n为当前数组的key则,n的父节点为 n>>1 或者 n/2(整除);n的左子节点l= n<<1 或 l=n*2,n的右子节点r=(n<<1)+1 或 r=l+1
代码如下 | 复制代码 |
$arr=array(1,8,7,2,3,4,6,5,9); //整理成大顶堆,最大的数整到堆顶,并将最大数和堆尾交换,并在之后的计算中忽略数组后端的最大数(last),直到堆顶(last=堆顶) //整理当前树节点($n),临界点$last之后为已排序好的元素 //如果右孩子比左孩子大,则让父节点的右孩子比 //交换两个值 |
相关文章
Laravel 调试工具 laravel-debugbar 打印日志消息
laravel-debugbar 调试工具的教程小编整理了几篇不错的教程,今天我们来看一篇Laravel 调试工具 laravel-debugbar 打印日志消息例子,希望文章对各位有帮助。 其实不...2016-11-25- 这篇文章主要为大家详细介绍了python实现学生通讯录管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-25
- 这篇文章主要介绍了Powershell 查询 Windows 日志的方法,需要的朋友可以参考下...2020-06-30
- MySQL日志主要包含:错误日志、查询日志、慢查询日志、事务日志、二进制日志;日志是mysql数据库的重要组成部分。日志文件中记录着mysql数据库运行期间发生的变化;也就是说用来记录mysql数据库的客户端连接状况、SQL语句...2015-11-24
- 这篇文章主要为大家详细解析了BootStrap栅格系统、表单样式与按钮样式源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2017-01-23
- 如今高要求的分布式系统的建造者遇到了不能完全由传统的面向对象编程(OOP)模型解决的挑战,但这可以从Actor模型中获益。...2021-05-20
- 护卫神·主机管理系统该版本支持在Windows Server 200320082012,含32位和64位,直接开设配置WEB站、FTP站,以及SQL Server和MySQL,是您开设和管理虚拟主机的绝好帮手。但是对于新用户可能在使用上有一些困难,因此请仔细阅读如下说明文档...2016-01-27
- 这篇文章主要介绍了C#实现线程安全的简易日志记录方法,比较实用的功能,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了利用C#修改Windows操作系统时间,帮助大家更好的利用c#操作系统,感兴趣的朋友可以了解下...2020-12-08
vivo OriginOS新系统如何更新 originos系统更新方法
vivo新系统更新的步骤是什么?如何更新到vivo的最新系统?vivo的最新系统太亮眼了,不少vivo的用户都在跃跃欲试想体验一下最新的系统。vivo新系统虽然做出来了不过我们想体验的话还是要等待一段时间。到时大家通过下面的方法就可以使用到新系统了...2020-12-08- 主键与外键的关系,通俗点儿讲,我现在有一个论坛,有两张表,一张是主贴 thread,一张是回帖 reply先说说主键,主键是表里面唯一识别记录的字段,一般是帖子id,体现在访问的时候,例如是 thread.php?id=1 表示我要访问的是帖子...2015-11-24
- 这篇文章主要介绍了c# 用Dictionary实现日志数据批量插入的步骤,帮助大家更好的理解和使用c#中的Dictionary类,感兴趣的朋友可以了解下...2021-02-01
C#3.0使用EventLog类写Windows事件日志的方法
这篇文章主要介绍了C#3.0使用EventLog类写Windows事件日志的方法,以简单实例形式分析了C#写windows事件日志的技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25- 这篇文章主要为大家详细介绍了C#实现影院售票系统,解析了售票系统的难点,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要介绍了Java SSM框架如何添加写日志功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-25
- 这篇文章主要介绍了c#接口使用的实例,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-17
- 一、数据访问对象 (DAO)YiiDAO 基于 PHP Data Objects (PDO) 构建。它是一个为众多流行的DBMS提供统一数据访问的扩展,这些 DBMS 包括MySQL, PostgreSQL 等等。因此,要使用 Yii DAO,PDO 扩展和特定的 PDO 数据库驱动(例如...2015-11-24
- 下面小编就为大家分享一篇c#快速写本地日志方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-06-25
ColorOS7.2好不好用 ColorOS7.2系统升级体验
ColorOS7.2系统怎么样?好不好用?值不值得升级?下面小编带来ColorOS7.2系统升级体验...2020-06-29- 这篇文章主要给大家介绍了关于sql server日志处理不当造成的隐患的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用sql server具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-07-11