Category Archives: PHP & MYSQL

composer安装包时报any version for your minimum-stability (stable)

今天要装一个包endroid/qrcode,可是死活装不上。
composer require 安装的时候一直报

[InvalidArgumentException]
Could not find package endroid/qrcode at any version for your minimum-stability (stable). Check the pac
kage spelling or your minimum-stability

然后新composer init一个空项目就能装上了。然后开始分析我的现有项目的composer.json文件。

最后发现是之前使用了国内的composer镜像,加上了一个配置


{
"repositories": [
{
"packagist": false
},
{
"type": "composer",
"url": "http://packagist.phpcomposer.com"
}
]
}

之前只把后一段给删了,没有删前一段。把前一段的“packagist”: false 也删了就好了。

php生成excel列名,超过26列大于Z的方法

这是phpExcel类中的方法。今天查到了,记录一下备忘。

public static function stringFromColumnIndex($pColumnIndex = 0)
	{
		//	Using a lookup cache adds a slight memory overhead, but boosts speed
		//	caching using a static within the method is faster than a class static,
		//		though it's additional memory overhead
		static $_indexCache = array();

		if (!isset($_indexCache[$pColumnIndex])) {
			// Determine column string
			if ($pColumnIndex < 26) {
				$_indexCache[$pColumnIndex] = chr(65 + $pColumnIndex);
			} elseif ($pColumnIndex < 702) {
				$_indexCache[$pColumnIndex] = chr(64 + ($pColumnIndex / 26)) .
											  chr(65 + $pColumnIndex % 26);
			} else {
				$_indexCache[$pColumnIndex] = chr(64 + (($pColumnIndex - 26) / 676)) .
											  chr(65 + ((($pColumnIndex - 26) % 676) / 26)) .
											  chr(65 + $pColumnIndex % 26);
			}
		}
		return $_indexCache[$pColumnIndex];
	}

将列的数字序号转成字母使用:

PHPExcel_Cell::stringFromColumnIndex($i); // 从o开始

将列的字母转成数字序号使用:

PHPExcel_Cell::columnIndexFromString(‘AA’);

Yii deleteByAttributs 用法,慎用Dao的delete

Yii框架一定要慎用Dao的delete,一不小心它生不成条件的话,就变成了整表删除。

可以用ActiveRecord的deleteByAttributes或deleteAll方法相对不容易写错。

deleteByAttributes用法如下:

MyClass::model()->deleteAllByAttributes(array(
    'phone_number'=>$phoneNumber,
));

或者第一个参数为空,使用第二个条件参数

MyClass::model()->deleteAllByAttributes(array(),'`phone_number` = :phone_number',array(
    ':phone_number'=>$phoneNumber,
));

或者使用deleteAll():

MyClass::model()->deleteAll('`phone_number` = :phone_number',array(
    ':phone_number'=>$phoneNumber,
));

再来一个带in条件的

$condition = new CDbCriteria();
$condition->addCondition('status=:status');
$condition->params = array(':status'=>1);
$condition->addInCondition('user_id',array(100111,100221,100221));
User::model()->deleteAll($condition);

Dao带in条件的示例


Yii::app()->db->createCommand()
->delete('mw_user', array('and', 'user_id=:user_id', array('in', 'position_id', array(1,2,3))),array(':user_id'=>121111));

但是请慎用DAO的delete,当你的条件写错一点,它将无法生成where条件,同时sql语句中也没有了where,但还不一定报错,结果就成了没有where的delete,结果会是整表被删除了。

php查询MongoDB遇到长整型的问题

困扰了我一天的问题。首先是Mongodb副本集。查php的Mongo扩展手册把副本集搞定。然后又是长整型时间的问题。

存进mongo的是java的长整型时间戳。而php是弱类型语言,且php的时间戳是11位。目前还是10位的阶段。转换成java的时间戳需要在后面补零。

// 生成java时间戳
$time = (string)$time.'000';
$time = (int)$time;

但是查询结果根本没有数据。把框架的Mongo用Debug打印出查询语句,没有问题。把查询语句直接在shell里查也没问题。但就是没数据。
后来打开Mongo的日志,调整级别为5,这样会记录查询语句。参照这里

发现我所查询的时间都变成了负数:“{ $gt: -154503944 }

然后万能的google找到了答案。php的长整型需要使用MongoInt64这个类来转换一下。虽然你在php中输出结果是一样的,但查询起来就不一样了。那么在上面的语句后面再加上一句就对了。

// 必须的一步,将长整形使用MongoInt64转换成64位整型
$time = new MongoInt64($time);

Mongo扩展的类参考在这里:http://www.php.net/manual/en/mongoint64.construct.php

Yii框架针对gbk编码的修改,CHtml可用,兼容php5.4

如果你的Yii框架不得已要使用gbk编码,你要做的有四件事:
1.复制一份儿框架中的中文语言包出来改为gbk编码,放在protected/messages,然后配置文件的components段中加入

// gbk编码的语言包
'coreMessages'=>array(
	//'basePath'=>null,
	'basePath'=>  dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'messages',
),

2.复制一份儿框架中的i18n中关于中文的文件改为gbk编码,放在protected/i18n/data下
然后config/main.php中加入

'localeDataPath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'../i18n/data',

3.复制一份儿框架中的views/exception.php到protected/views/system,改一下里面的编码为gbk,默认是utf8,否则调试页面就乱码了。

4.修改CHtml类:

CHtml类使用了htmlspecialchars来格式化输出,但htmlspecialchars不支持gbk编码。
当然,你可以把htmlspecialchars的编码去掉,但php5.4这样做时,就会没有输出。
一共改两个方法,一个是encode,还有一个encodearray

如果你使用了apc的话,请修改框架目录中yiilite.php中对应的两个方法。

如果你不使用apc的话,并且像我一样不愿意修改框架本身,可以把Chtml复制一份出来然后使用Yii的classmap来自定义这个类的路径。然后在入口文件处来定义,例如我的:

require_once ($yii);
// 重写yii class map,使用自定义的CHtml。 yiilite中的代码要手动修改不能使用此方法覆盖
Yii::$classMap=array('CHtml'=>__DIR__.'/../protected/extensions/helpers/CHtml.php');

下面是要修改的CHtml类中的两个方法

public static function encode($text)
{
	if(PHP_VERSION < '5.4.0') {
		return htmlspecialchars($text,ENT_QUOTES);
	}
	else
	{
		if(strtolower(Yii::app()->charset) == 'utf-8') {
			$charset = 'UTF-8';
		} else {
			$charset = 'ISO-8859-1';
		}
		return htmlspecialchars($text,ENT_QUOTES,$charset);
	}

	return htmlspecialchars($text,ENT_QUOTES,Yii::app()->charset);
}
public static function encodeArray($data)
{
	$d=array();
	foreach($data as $key=>$value)
	{
		if(is_string($key))
			$key=self::encode($key);
		if(is_string($value))
			$value=self::encode($value);
		else if(is_array($value))
			$value=self::encodeArray($value);
		$d[$key]=$value;
	}
	return $d;
}

 

mamp 2.0.5 安装 Zend Optimizer

MAMP2.0版本默认取消了对Zend Optimizer的支持。这也可以理解,这东西活到现在的确已经没啥意义了。

但是shopex这烂货,7年了,还TM加密,真是无语。我05年的用户,偶然登陆shopex居然因为系统升级把我所有的授权都弄没了。两天了还没搞定。再度BS一下。

言归正传,参考了一德国人的blog,是因为apache 32位和64位的问题。

首先肯定是下载Optimizer扩展,从这里下载for macos的就可以,然后把对应的php5.2.x版本的ZendOptimizer.so文件copy到

/Applications/MAMP/bin/php/php5.2.17/lib/php/extensions/no-debug-non-zts-20060613/

php.ini中设置为:

[Zend]
zend_extension="/Applications/MAMP/bin/php/php5.2.17/lib/php/extensions/no-debug-non-zts-20060613/ZendOptimizer.so"
zend_optimizer.enable_loader = 1
zend_optimizer.optimization_level=15

然后执行:

mv /Applications/MAMP/Library/bin/httpd /Applications/MAMP/Library/bin/httpd.64
lipo -thin i386 /Applications/MAMP/Library/bin/httpd.64 -output /Applications/MAMP/Library/bin/httpd.32
ln -s /Applications/MAMP/Library/bin/httpd.32 /Applications/MAMP/Library/bin/httpd

然后重启即可。查看phpinfo看看有没有“with Zend Optimizer v3.3.9”,有则成功。

Mac OS X 安装mysql过程

从mysql官网http://mysql.com/downloads/mysql/下载dmg格式的安装文件。推荐使用64位(x86, 64-bit)。

打开安装包,第一个扩展名为pkg的文件即是安装文件。mysql不必编译安装,直接运行pkg安装即可。MySQL的Mac OS X PKG安装到/usr/local/mysql-VERSION,并且还会生成一个符号连接,/usr/local/mysql,指向新的位置。如果有/usr/local/mysql目录,首先将它改名为/usr/local/mysql.bak。安装完后,安装器会自动执行mysql_install_db在MySQL数据库中创建授权表。

安装完成后,双击MySQL.prefPane文件,即可给系统编好设置添加一个mysql的管理面板,可以在系统偏好设置中开启和关闭mysql。

如果安装了MySQL.prefPane这个偏好设置项,打开系统偏好设置会看到新增一项“MySQL”项。打开后可以启动和停止mysql服务。同时可以看到下方有个单选框“Automatically Start MySQL Server on Startup”,就是是否随系统开机启动Mysql服务,选中它的话,下面这项MySQLStartupItem.pkg就不必安装了。

MySQLStartupItem.pkg这个文件是干吗的呢?它提供了mysql随mac系统开机启动的功能。如何取消随系统启动呢?前面刚刚说完,不选中随机启动就行了。

仔细阅读readme.txt文件会发现,你可以为mysql和mysqladmin做两个alias。这样就不必每次输入完整路径来执行mysql和mysqladmin了。

Continue reading

sql查询优化小结

1. SQL优化的原则是:将一次操作需要读取的BLOCK数减到最低,即在最短的时间达到最大的数据吞吐量。
调整不良SQL通常可以从以下几点切入:

  • 检查不良的SQL,考虑其写法是否还有可优化内容
  • 检查子查询 考虑SQL子查询是否可以用简单连接的方式进行重新书写
  • 检查优化索引的使用
  • 考虑数据库的优化器

2. 避免出现SELECT * FROM table 语句,要明确查出的字段。

3. 在一个SQL语句中,如果一个where条件过滤的数据库记录越多,定位越准确,则该where条件越应该前移。

4. 查询时尽可能使用索引覆盖。即对SELECT的字段建立复合索引,这样查询时只进行索引扫描,不读取数据块。

5. 在判断有无符合条件的记录时建议不要用SELECT COUNT (*)和select top 1 语句。

6. 使用内层限定原则,在拼写SQL语句时,将查询条件分解、分类,并尽量在SQL语句的最里层进行限定,以减少数据的处理量。

7. 应绝对避免在order by子句中使用表达式。

8. 如果需要从关联表读数据,关联的表一般不要超过7个。
Continue reading