在不改变php.ini中 session.save_handler = files 的前提下,实现不生成文件session,后期可写入到数据库。

<?php
//原创:xuduowei,想学习php开发的可以找我。微信号:weilanweb
class session_mysql{
		//private static $db=null;
		private static $ip=null;
		private static $lifetime=null;
		private static $time=null;

		private static function init(){
			//self::$db=$db;
			self::$ip=!empty($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : "unknown";
			self::$lifetime=ini_get('session.gc_maxlifetime');
			self::$time=time();
		}

		public static function start(){
			self::init();
			
			session_set_save_handler(
				array(__CLASS__, "open"),
				array(__CLASS__, "close"),
				array(__CLASS__, "read"),
				array(__CLASS__, "write"),
				array(__CLASS__, "destroy"),
				array(__CLASS__, "gc")
			);
			session_start();
		}

		public static function open($path, $name){
			//return true;
		}
	
		public static function close() {
			//return true;
		}
		
		public static function read($id){
			echo "read读取信息<br>";			
		}
		
		public static function write($id ,$data){
			echo "write写信息<br>";			
			//return true;
		}
		
		public static function destroy($id){
			echo "destroy清除信息<br>";
			
		}
		
		private static function gc($lifetime){
			echo "gc回收信息<br>";
		
		}

	
}

session_mysql::start();
echo session_name().'='.session_id()."<br>";
?>

输出结果:

read读取信息
PHPSESSID=2jo24tkjjqgu8jq1p6u2aijnd3
write写信息
=========================================
以phpstudy环境为例:默认的J:\phpStudy\tmp\tmp session存储路径下并不会有session文件的存储。php.ini配置文件中依然是默认的:session.save_handler = files
=========================================

这样做的目的就是方便后期把session写入数据库中。

以下为数据库融合版【xuduowei 原创】:

class db{
	var $conn;
	function __construct(){
		$conn=mysqli_connect("主机","用户名","密码");//为了方便,我这直接写。
		if(!$conn){
			echo "数据库连接失败";
			die;
		}
		mysqli_select_db($conn,"数据库");//为了方便,我这直接写。
		$this->conn=$conn;	
		//return $conn;
	}

	function select($sql){	
		$rst=mysqli_query($this->conn,$sql);
		$arr=array();
		while($rs=mysqli_fetch_assoc($rst)){
			$arr[]=$rs;
		}
		return $arr;
	}

	function query($sql){
		//用户数据库的删除操作	
		return mysqli_query($this->conn,$sql);		
	}
}//end db


class session_mysql{
		private static $db=null;
		private static $ip=null;
		private static $lifetime=null;
		private static $time=null;

		private static function init($db){
			self::$db=$db;
			self::$ip=!empty($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : "unknown";
			self::$lifetime=ini_get('session.gc_maxlifetime');
			self::$time=time();
		}

		public static function start($db){
			self::init($db);
			
			session_set_save_handler(
				array(__CLASS__, "open"),
				array(__CLASS__, "close"),
				array(__CLASS__, "read"),
				array(__CLASS__, "write"),
				array(__CLASS__, "destroy"),
				array(__CLASS__, "gc")
			);
			session_start();
		}

		public static function open($path, $name){
			return true;
		}
	
		public static function close() {
			return true;
		}
		
		public static function read($id){
				echo "read读取信息<br>";
			
				$sql="select sessionid,updatetime,data from xdw_session where sessionid='".$id."'";	
				$result=self::$db->select($sql);
				if(!$result[0]){//若没有值,就返回空。
					return "";
				}

				if ((strtotime($result[0]["updatetime"])+self::$lifetime) < self::$time){
					//echo "时间过期";
					self::destroy($id);
					return '';
				}

				return $result[0]['data'];
		 
				
		}

	
		public static function write($id ,$data){//sessionid和session 值
			echo "write写信息<br>";	

			$sql="select sessionid,updatetime,data from xdw_session where sessionid='".$id."'";	
			
			$result=self::$db->select($sql);
			//若有值
			if($result[0]){
				//若session内容不一致,或者超出一段时间300秒了【还没有过期】。我们就重新更新一次。
				if($result[0]['data'] != $data || self::$time > (strtotime($result[0]['updatetime'])+300)){
					$sql="update xdw_session set updatetime = '".date("Y-m-d H:i:s")."', data ='".$data."' where sessionid ='".$id."'";
					self::$db->query($sql);
				}

			}else{//若没有值,就所以这个sessionid不存在。我们就重新写入一次。
				$sql="insert into xdw_session set updatetime = '".date("Y-m-d H:i:s")."', data ='".$data."' ,sessionid ='".$id."'";
				self::$db->query($sql);
			}

			return true;
		}
	

		public static function destroy($id){
			echo "destroy清除信息<br>";				
			$sql="delete from xdw_session where sessionid ='".$id."'";			
			self::$db->query($sql);

			return true;				
			
		}
		
		private static function gc($lifetime){
			echo "gc回收信息<br>";//也就是删除过期的

			$time=self::$time-$lifetime;
			$sql = "delete from xdw_session where unix_timestamp(updatetime) < ".$time;
			self::$db->query($sql);		
			return true;
		
		}

	
}

session_mysql::start(new db());
echo session_name().'='.session_id()."<br>";

$_SESSION['username']="xuduowei";
附上数据库表结构:
#有想学习php开发的,可以联系我。电话:15309695130  php著名老师:xuduowei

DROP TABLE IF EXISTS `xdw_session`;
CREATE TABLE `xdw_session` (
  `session_id` varchar(32) NOT NULL,
  `data` text NOT NULL,
  `expire` datetime NOT NULL,
  PRIMARY KEY (`session_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

xuduowei 原创作品,请勿转载,谢谢合作。


关注公众号,了解更多it技术(it问答网

js jquery中判断checkbox是否被选中的方法

在js中:

document.getElementById(“checkboxID”).checked   返回true或者false

jQuery中:

$(“input[type=’checkbox’]”).is(‘:checked’) 返回true或false

1、attr()方法  设置或者返回备选元素的值

attr(属性名)    //获取属性的值

attr(属性名,属性值)   //设置属性的值

$(“#id]”).attr(“checked”)  JQ1.6之后返回checked或者是undefined  (1.6之钱返回true或者是false)

$(“input[type=’checkbox’]”).attr(“chacked”,true);  将多选框设为全选中状态  false为不选中状态

2、prop()方法
$(“input[type=’checkbox’]”).prop(“checked”)  返回true或者false

还有removeAttr(属性名)、removeProp(属性名)删除该属性

例:

$(“input[‘tupe=checkbox’]”).removeAttr(“checked”);移除多选框的选中。

如下代码实现多个checkbox得到对应的属性值。非常经典,项目中必用。

$(document).on("change",'.sku_value',function(){			
					str=Array();
					$(".sku_value").each(function () { 
						var s=$(this).attr('propvalid');
						if($(this).is(":checked")){
							str.push(s);
						}
					});

					alert(str);

			});

 


关注公众号,了解更多it技术(it问答网

mysql表数据发生变化时,主动通知业务系统(mysql-udf-http)

近期接到一个任务,在商家的商品信息发生改变后,要及时通知商家的业务系统,并将变更后的数据同步过去。
第一时间想法是,在主系统的商家编辑模块插入对应代码,当商品编辑后,发送商品id至MQ中,子系统消息订阅,并进行相应处理,感觉不错,但是在主系统进行扩展,系统代码会越来越臃肿。
有没有更好的解决方案,比如让mysql主动通知业务系统,数据发生变化了?于是找到了mysql-udf-http。

mysql-udf-http 是一款简单的MySQL用户自定义函数,具有http_get()、http_post()、http_put()、http_delete()四个函数,可以在MySQL数据库中利用HTTP协议进行REST相关操作,它的安装方式如下:

tar zxvf mysql-udf-http-1.0.tar.gz
cd mysql-udf-http-1.0/
./configure --prefix=/usr/local/mysql --with-mysql=/usr/local/mysql/bin/mysql_config
make && make install

如果提示缺少libcurl,就安装curl

yum install curl*

正常的情况mysql-udf-http.so等文件将安装至/usr/local/mysql/lib/plugin下,不知什么原因我的装在了/usr/local/mysql/lib/mysql/plugin下,于是加个软链

正常的情况mysql-udf-http.so等文件将安装至/usr/local/mysql/lib/plugin下,不知什么原因我的装在了/usr/local/mysql/lib/mysql/plugin下,于是加个软链

安装成功后,进到mysql控制台,注册相关函数

create function http_get returns string soname 'mysql-udf-http.so';
create function http_post returns string soname 'mysql-udf-http.so';
create function http_put returns string soname 'mysql-udf-http.so';
create function http_delete returns string soname 'mysql-udf-http.so'; 

然后在业务表中加入更新操作的触发器

DELIMITER |  
DROP TRIGGER IF EXISTS test_update;  
CREATE TRIGGER test_update  
AFTER UPDATE ON test  
FOR EACH ROW BEGIN  
    SET @tt_re = (SELECT http_get(CONCAT('http://192.168.0.1:8080/my.do?id=', OLD.id)));  
END |  
DELIMITER ;

经测试,当商品表中的数据有更新时,mysql会发送get请求至业务系统。

INSERT 触发器

DELIMITER |  
DROP TRIGGER IF EXISTS test_insert;  
CREATE TRIGGER test_insert  
AFTER INSERT ON test
FOR EACH ROW BEGIN  
    SET @tt_re = (SELECT http_get(CONCAT('http://192.168.0.1:8080/my.do?id=', OLD.id))); 
END |  
DELIMITER ;

DELETE 触发器

DELIMITER |  
DROP TRIGGER IF EXISTS test_delete;  
CREATE TRIGGER test_delete  
AFTER DELETE ON test  
FOR EACH ROW BEGIN  
    SET @tt_re = (SELECT http_get(CONCAT('http://192.168.0.1:8080/my.do?id=', OLD.id)));  
END |  
DELIMITER ; 

下载地址
http://code.google.com/p/mysql-udf-http

csdn下载
http://download.csdn.net/detail/cyantide/9455805

来源:https://blog.csdn.net/cyantide/article/details/50828746

借鉴:https://www.cnblogs.com/phpper/p/7587031.html


关注公众号,了解更多it技术(it问答网

我们项目开发中,应该从哪几个方面提高项目性能?

我们项目开发中,应该从哪几个方面提高项目性能?【原创】

1、硬件;服务器要稳定,可靠,带宽大,允许的并发数要高;
2、软件【开发的程序】。

a、数据库
1、创建合适的字段类型及分配合适的长度;

例如:

密码:md5加密,对应的字段:char 32
年龄:tinyint 无符号

提示:整型的长度是结合0填充一起使用的。

2、默认值尽可能不要设置null

3、索引的创建;

4、合理的分表设计。

b、程序中值的调取【从数据库中调取】

单表查询,多表查询

子查询;【性能较低】
左右链接;
关联查询;

合理的 select 字段1,字段2 from 表
不合理的 select * from 表

不合理的 select count(*) from 表 where >>>
不合理的 select count(姓名) from 表 where >>>
合理的 select count(主索引ID) from 表 where >>>

c、优化。
1、静态化;
2、缓存[1、页面缓存;2、内存缓存]。


关注公众号,了解更多it技术(it问答网

php 控制同一个用户只能同时一个人在线

有时候项目要求:控制同一个用户只能同时一个人在线

网上有说到很多种方法。不管哪种方法,都要注意2个特殊情况:

1、关闭浏览器;2、电脑断电【计算机系统中断】;

徐多蔚,徐老师,合肥php老师 这里分享一个稳定,高效,安全的解决方案:

核心效果:类似QQ登录一样,以最后一次登录为准。

若你当前在A电脑登录中【login_session 表记录:session_id,登录名,状态=1】,然后又在B电脑登录【首先:删除login_session表中和当前用户名同名的记录,或者更新和当前用户名同名的记录登陆状态为0;然后login_session 表记录:session_id,登录名,状态=1】,当在A电脑操作的时候,会判断当前登录状态为1才可以操作。这个时候发现为0了,则提示你的账号在其他地方登陆。

徐多蔚,徐老师,合肥php老师


关注公众号,了解更多it技术(it问答网

JAVA和JSP之间的关系

我现在给你一个JAVA和JSP之间的关系,以及JAVA的完整认识

JAVA分为J2EE,J2SE.J2ME,下面分别介绍:

一.J2EE:Java 2 Platform Enterprise Edition 企业版,用于企业应用,支持分布式部署。

J2EE平台由一整套服务(Services)、应用程序接口(APIs)和协议构成,
它对开发基于Web的多层应用提供了功能上的支持。它包含13种核心技术规范:
(1)Java Database Connectivity (JDBC)
以一种统一的方式来对各种各样的数据库进行存取
(2)Java Naming and Directory Interface (JNDI)
用于名字和目录服务,它提供了一致的模型来存取和操作企业级的资源如DNS和LDAP,本地文件系统等
(3)Enterprise Java Beans (EJB)
提供了一个框架来开发和实施分布式商务逻辑,显著地简化了具有可伸缩性和高度复杂的企业级应用的开发
(4)JavaServer Pages (JSPs) 这里就是你所说的JSP!!!!!!用以创建动态网页
(5)Java servlets
提供的功能大多与JSP类似,不过实现的方式不同
(6)Remote Method Invocation (RMI)
在远程对象上调用一些方法,使用了连续序列方式在客户端和服务器端传递数据
(7)Interface Description Language (IDL)
将Java和CORBA集成在一起
(8)Java Transaction Architecture (JTA)
可以存取各种事务
(9)Java Transaction Service (JTS)
规定了事务管理器的实现方式
(10)JavaMail
用于存取邮件服务器的API,它提供了一套邮件服务器的抽象类
(11)JavaBeans Activation Framework(JAF)
JavaMmail利用JAF来处理MIME-编码的邮件附件,MIME的字节流可以被转换成JAVA对象,或者转换自JAVA对象
(12)Java Messaging Service (JMS)
是用于和面向消息的中间件相互通信的应用程序接口(API)
(13)Extensible Markup Language (XML)
XML是一种可以用来定义其它标记语言的语言
上面的JSP是主流,基于MVC的实现,最流行使用,也最安全(比较其他语言做的网站)
其中EJB是java最难学的东西
但是现在的sun公司出来一种新的技术:java FX,
可以像FLASH一样在浏览器中执行,但是也要安装插件,具体可以参见www.sun.com
二.J2SE:Java 2 Platform Standard Edition 标准版,用于桌面应用,也是J2EE的基础。

包括JAVA基础,IO,Swing,AWT,线程,集合等知识.也是学习JAVA的必经之路(基础)!
三.J2ME:Java 2 Platform Micro Edition 移动版用于小型设备,是J2SE的一个子集。

主要的技术如下:

Connected Limited Device Configuration【CLDC】:是组成资源有限的移动信息设备的 Java 运行时环境的两种配置之一。CLDC 描述最基本的库和虚拟机特性,所有包含 K 虚拟机(K virtual machine,KVM)的 J2ME 环境实现中都必须提供这些库和特性。
Mobile Information Device Profile【MIDP】:是组成资源有限的移动信息设备的 Java 运行时环境的两种配置之一。MIDP 提供核心应用程序功能,包括用户界面、网络连接、本地数据存储和应用程序生命周期管理。
Connected Device Configuration【CDC】:是一个基于标准的框架,用来构建和交付可以跨许多连接网络的消费类设备和嵌入式设备共享的应用程序。
Mobile 3D Graphics API for J2ME【M3G】:是一种轻量的交互式 3D 图形 API,它作为可选的包与 J2ME 和 MIDP 结合使用。

所以你所说的JAVA和JSP的关系就这样豁然开朗!

JAVA是一种编程语言,可以编写应用程序,主要应用在网络编程上。 
JSP是建立在JAVA基础上的一种网络编程语言,只能在网页上应用。 
JavaScript是一种Web脚本语言,可以嵌入在HTML中,可以由浏览器解释执行。

可以把jsp理解为脚本

java为面向对象语言

jsp作用主要是负责页面展现,java负责逻辑,业务处理

jsp 本质 是servlet,servlet本质是 java类,就是这么个关系。


关注公众号,了解更多it技术(it问答网

ajax中获得处理接口传过来的xml

$.ajax({
   type: "POST",
   url:"http://127.0.0.1/jk/xml.php",
 
   data: "",
   success: function(xml){
			obj=$(xml).find("teacher");
			alert(obj.text());//弹出内容 xuduowei
			


   }
});

xml.php 接口 code:

<?php
$xmlstring=<<<XML

 
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<student>xue</student>
<teacher>xuduowei</teacher>
</persons>
 
XML;

echo $xmlstring;
?>

 


关注公众号,了解更多it技术(it问答网

ajax中 json字符串或者json对象的处理。

若对应的json传递过来的是json对象【php中json_encode($arr) 就是json对象】。

ajax,js中,可以用 var json=JSON.parse(msg);处理转成数组。注意:JSON.parse兼容性不好,还是推荐用:eval(“(“+msg+”)”);转成对象。

 

但是若接口文件php中直接输出的是json字符串,则我们需要使用:

//我们需要将eval()方法将这个字符串包一下,就可以转成JSON对象了

var json = eval(‘(‘ + msg + ‘)’);

如果用错了,会报错的!

SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON

一定要区分开!

 

模拟JS代码如下:

<script src="jquery.min.js"></script>
<script>
	$.ajax({
   type: "POST",
   url:"http://127.0.0.1/jk/json.php",
  //url: "https://api.miaodiyun.com/20150822/industrySMS/sendSMS",
 //  data: "accountSid=c754405c64bd493188b56a5b781dc5ff&smsContent=【秒嘀科技】您的验证码是345678,30分钟输入有效。    &to=13896543210&timestamp=20150821100312&sig=96d3adac3d2f43b8a85b0aeb201ab2be&respDataType=JSON",
   success: function(msg){
    // alert( "Data Saved: " + msg );
			//var json=JSON.parse(msg);//这个不行,用下面的
		
			var json = eval('(' + msg + ')');
			// alert(json.respDesc);
			 var respDesc=json.respDesc;
				alert(respDesc);
			// if(respDesc=="成功"){
				//alert('接收成功');
			// }

			//alert(11);

   }
});
</script>

模拟接口文件代码:

<?php
$str=<<<xdw
{
"respCode":"00000",
"respDesc":"成功",
"failCount":"1",
"failList":
[
    {
        "phone":"13896543210",
        "respCode":"00111",
        "respDesc":"匹配到黑名单",
    }
],
"smsId":"913945fec0204b1e94baa75a5c013f59"
}
xdw;


echo $str;//这里输出的是json字符串,不是对象。


?>

 


关注公众号,了解更多it技术(it问答网

xml中的<![CDATA[]]>和转义字符

<![CDATA[]]>这个标记所包含的内容将表示为纯文本,比如<![CDATA[<]]>表示文本内容“<”
此标记用于xml文档中,我们先来看看使用转义符的情况。我们知道,在xml中,”<””>””&”等字符是不能直接存入的,否则xml语法检查时会报错,如果想在xml中使用这些符号,必须将其转义为实体,如”&lt;””&gt;””&amp;”,这样才能保存进xml文档。
在使用程序读取的时候,解析器会自动将这些实体转换回”<””>””&”。举个例子:
<age> age < 30 </age>
上面这种写法会报错,应该这样写:
<age> age &lt; 30 </age>
值得注意的是:
(1)转义序列字符之间不能有空格;
(2) 转义序列必须以”;”结束;
(3) 单独出现的”&”不会被认为是转义的开始;
(4) 区分大小写。在XML中,需要转义的字符有:
(1)&   &amp; 
  (2)<   &lt; 
(3)>   &gt;
(4)"   &quot;
(5)'   &apos;
但是严格来说,在XML中只有”<”和”&”是非法的,其它三个都是可以合法存在的,但是,把它们都进行转义是一个好的习惯。
不管怎么样,转义前的字符也好,转义后的字符也好,都会被xml解析器解析,为了方便起见,使用<![CDATA[]]>来包含不被xml解析器解析的内容。但要注意的是:
(1) 此部分不能再包含”]]>”
(2) 不允许嵌套使用;
(3)”]]>”这部分不能包含空格或者换行。
最后,说说<![CDATA[]]>和xml转移字符的关系,它们两个看起来是不是感觉功能重复了?
是的,它们的功能就是一样的,只是应用场景和需求有些不同:
(1)<![CDATA[]]>不能适用所有情况,转义字符可以;
(2) 对于短字符串<![CDATA[]]>写起来啰嗦,对于长字符串转义字符写起来可读性差;
(3) <![CDATA[]]>表示xml解析器忽略解析,所以更快。

用PHP5的SimpleXML解析XML文档

www.xuduowei.com/archives/91

 


关注公众号,了解更多it技术(it问答网