猫窝私语 — Makumo's Blog

玛酷猫的温馨小窝,记录生活点点滴滴。

@玛酷猫3 年前

06/24
14:16
PHP

升级PHP8踩坑记

最近后台总是提示当前使用PHP(7.2)版本过低,建议升级7.4。看着着实难受,干脆直接升到8.0好了,免得过段时间又开始不停的弹提示。说干就干,作为一个懒人,本着能yum坚决不make的态度,先去查了下remi源里面,已经有了8.0的版本。

yum repolist all |grep php

没有remi源的话可以用下面命令添加

yum -y install https://mirrors.aliyun.com/remi/enterprise/remi-release-7.rpm

后面的就简单了

# 先卸载掉老的版本
yum remove php-*
# 切换PHP8的源
yum-config-manager --enable remi-php80
# 安装
yum install php-cli php-fpm php-mysqlnd php-zip php-devel php-gd php-mbstring php-curl php-xml php-pear php-bcmath php-json php-redis php-opcache

然后重启httpd,然后就是经典的报错了。。错误代码Invalid command ‘php_admin_value’。查了下站点的配置文件,使用的是如下配置

php_admin_value open_basedir "站点目录:/tmp/:/var/tmp/:/proc/"

这是将php作为httpd的一个module使用,为嘛使用这个已经无法考证了,估计八成多年前从哪抄来的。网上搜了下,基本都是说httpd缺少module,在编译的时候需要修改配置,加上–with-apxs2参数,要重新编译。我这是直接yum的,这个就跳过。此外还有更换调用方法,例如FastCGI模式,将php-fpm作为服务启动,httpd将.php的请求发送到php-fpm服务上。懒人理念直接跳过,google上翻了半天,终于找到了解决办法,一句话

yum install mod_php

这才对嘛,既然是yum安装的问题,肯定可以用yum的方法解决。重启httpd,已经正常启动,打开网站,500错误,意料之中,毕竟大版本升级。查看了下httpd的日志,某个10年前的插件中还存在这个函数create_function(),而货已经在8中被干掉了,直接删除了这个插件。刷新,页面轻松打开,重新查看了下日志,一大堆PHP Warning,都是插件的问题,这个就主要等着各位插件作者后续更新了。

升级PHP8踩坑记

@玛酷猫9 年前

09/17
12:27
PHP

如何用PHP裁出一个圆

先说下需求:前段时间神秘花园很火,于是乎客户想要制作神秘花园的网页游戏,涂色盘是圆形的,网页将涂色盘加载进当前的canvas中,当网友涂色完毕提交后,将canvas内容转化为图片数据传送至后台保存。这时接收到的数据包括整个canvas内容,整体是个矩形,除了网友涂色部分,还有整个背景、颜色盘、一些按钮之类的,这就需要把网友涂色的那个圆形部分裁剪下来。

我的思路分成两部分,首先裁剪成正方形,毕竟直接在矩形上面裁出一个圆相对来说麻烦一些。项目使用的thinkphp框架(v3.1),裁正方形还是比较快捷的,直接调用自带的函数即可

import('ORG.Util.Image.ThinkImage');
$image = new ThinkImage(THINKIMAGE_GD, $file);
$image->crop(516,516,45,119)->save($file);//crop四个参数分别为长、宽、x偏移、y偏移

下一步就是要裁圆了,网上搜索了下居然没有搜索到多少有用的代码,感觉这个对大家都不是什么难处,看来自己这个半路出家的基础还是不太好呀。幸好在一个很老的帖子(08年的帖子)的回帖里面看到Sunyanzi@phpchina的一个思路,原帖地址传送门,代码如下:

<?php
//-----------------------------------------------------------
// * Sunyanzi @ phpchina
//-----------------------------------------------------------

class image_cutter {
	private $original_image;
	private $cutted_image;
	private $diameter;
	private $radius;

	public function __construct( $image_path ) {
		/* load the original image ... */
		$image = imagecreatefromjpeg( $image_path );
		/* get image size ... */
		$x = imagesx( $image );
		$y = imagesy( $image );		
		/* diameter of the circle is always the smaller side ... */
		$this->diameter = $x > $y ? $y : $x; 
		/* radius is half a diameter ... am i must explain this ...? */
		$this->radius = $this->diameter / 2;		
		/* save the original image ... */
		$this->original_image = $image;		
		/* create new canvas to save our work ... */
		$this->create_blank_image();		
		/* PAINTING TIME ... */
		$this->read_the_original_image_and_write();		
		/* i'm positively bursting to see what we have done ... */
		return;
	}

	private function __destruct() {
		/* hey my dear brower ... it's not a html page comes ... */
		header("Content-type: image/png");
		/* show our work ... */
		imagepng( $this->cutted_image );
		/* we have to cleaned up the mass before left ... */
		imagedestroy( $this->original_image );
		imagedestroy( $this->cutted_image );		
		/* so ... how do you think about this ...? */
		return;			
	}

	private function create_blank_image() {			
		/* create a true color square whose side length equal to diameter of the circle ... */
		$image = imagecreatetruecolor( $this->diameter,$this->diameter );
		/* we also need a transparent background ... */
		imagesavealpha($image, true);
		/* create a transparent color ... */
		$color = imagecolorallocatealpha($image, 0, 0, 0, 127);
		/* ... then fill the image with it ... */
		imagefill($image, 0, 0, $color);		
		/* nothing to do then ... just save the new image ... */
		$this->cutted_image = $image;		
		/* go back and see what should we do next ..? */
		return;			
	}

	private function read_the_original_image_and_write() {
		/* actually we need a smooth circle ... */
		for ( $x = 0; $x <= $this->radius; $x += 0.01 ) {
			/* standard form for the equation of a circle ... don't tell me you never knew that ... */
			$y = sqrt( $this->diameter * $x - pow( $x , 2 ) ) + $this->radius;
			/* i think i should call this successive scans ... */
			for ( $i = $x; $i < $this->diameter - $x; $i++ ) {
				/* half of the circle ... */
				imagesetpixel (
					$this->cutted_image , $i, $y, 
					imagecolorat( $this->original_image, $i, $y )
				);

				/* the other half of course ... */
				imagesetpixel ( 
					$this->cutted_image , $i, $this->diameter - $y, 
					imagecolorat( $this->original_image, $i, $this->diameter - $y ) 
				);
			}				
		}
			
		/* avoid the white line when the diameter is an even number ... */
		if ( ! is_float( $this->radius ) )
			for ( $i = 0; $i < $this->diameter; $i++ )
				imagesetpixel ( 
								$this->cutted_image , $i, $this->radius - 1,
								imagecolorat( $this->original_image, $i, $this->radius - 1 )
				);						
		/* woo ... not as difficult as you think ... that's all ... */
		return;
	}
}

new image_cutter( HERE_COMES_THE_ORIGINAL_IMAGE_PATH );
?>

读了下代码,大概了解了下原理,以x轴为参考,0.01像素步长,通过圆的公式计算出对应y点的位置,然后将循环将X轴这条线上落在y点外(圆外)的点用透明色填充。实际放到项目中测试,发现个问题,由于项目中圆的半径比较大,516像素,按照0.01步长来计算,在x刚起步时,计算后的y值之间的间隔会大于1个像素,表现在页面上就是在圆的中间出现两条白线,将步长减少到0.004的时候白线消失,但是由于步长变小,整个循环数目变大,耗时严重,一次将近30秒的时间。

既然Sunyanzi提供了一个思路,那我就把它简化下,毕竟图片最小点是像素,那我就以1像素为步长,y轴也不计算了,直接也以1像素为步长,通过圆的方程式算出半径,比较半径的大小,大于我需要的圆的半径的点,把他用透明色填充掉就OK了。思路有了就开始动手。仅修改上面代码中裁圆的那个函数read_the_original_image_and_write()

private function read_the_original_image_and_write(){
        for ( $x = 0; $x <= $this->radius; $x++ ) {
            for ( $y = 0; $y <= $this->radius; $y++ ) {
                if(sqrt( pow( $x- $this->radius , 2 ) + pow( $y- $this->radius , 2 ))<$this->radius){
                    imagesetpixel (
                        $this->cutted_image , $x, $y,
                        imagecolorat( $this->original_image, $x, $y )
                    );
                    imagesetpixel (
                        $this->cutted_image , $this->diameter - $x, $y,
                        imagecolorat( $this->original_image, $this->diameter - $x, $y )
                    );
                    imagesetpixel (
                        $this->cutted_image , $x, $this->diameter - $y,
                        imagecolorat( $this->original_image, $x, $this->diameter - $y )
                    );
                    imagesetpixel (
                        $this->cutted_image ,$this->diameter -  $x, $this->diameter - $y,
                        imagecolorat( $this->original_image, $this->diameter - $x, $this->diameter - $y )
                    );
                }
            }
        }
    }

实际效果速度那是没说的,毕竟简化了,基本上秒出,效果相对之前的方法来说差了点,一周的锯齿感强了点,不过由于图片比较大,反倒不是很明显,有需要的话可以将步长调到0.5,效果会好一点,速度不是太影响,图片小的话可以放得更低一点。上面例子是直接输出图片,实际应用为保存成文件,这个就比较简单了,就不在这里贴代码了。

如何用PHP裁出一个圆

@玛酷猫10 年前

04/29
12:05
计算机

Laravel 学习(二)数据库建立与迁移

继续按着教程走,Laravel自带了一个用户系统,http://站点/home 即可直接访问,不过由于没有数据库部分,登陆和注册都是铁定报错的。Laravel鼓励敏捷、迭代的开发方式,所以Laravel迁移给你提供了一种在迭代方式中修改数据库架构的手段,它不要你用SQL操作,而是允许你使用PHP代码。Laravel架构生成器允许我们快速创建数据库表和插入列或索引。它使用清洁和富有表现力的语法来操作数据库。Laravel迁移可以当作数据库的版本控制。

按着教程来,首先先修改数据库配置文件,在Laravel文件下下面的.env文件

DB_HOST=localhost
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=123456

接着运行命令执行数据库迁移操作

php artisan migrate

以上都是按照在linux环境下,而我本地环境是IIS,必然就是各种坑爹错误。搜索了下网上关于IIS下运行Laravel资料很少,琢磨了下无外乎路径问题。

首先是php路径,如果没有配置,直接运行php会提示“php 不是内部或外部命令,也不是可运行的程序
或批处理文件。” 依次右击桌面上的“计算机”,选择“属性”,选择“高级系统设置”,点击“环境变量”,在系统变量中找到“Path”并双击,在变量最后面加上php的文件夹,例如我的php文件夹“D:\Work\work-dll\php-5.6.7”(我配置的时候Path里面已经有了,估计应该是安装composer的时候写入的)

然后依次左下角“开始”,点击运行,输入“CMD”回车,WINDOWS8便利很多,直接WIN+X,选“命令提示符”,敲命令进入站点目录,然后执行数据库迁移操作,比如我的

C:\Users\makumo>d:
D:\>cd Work\work-zone\wwwroot\laravel
D:\Work\work-zone\wwwroot\laravel>
D:\Work\work-zone\wwwroot\laravel>php artisan migrate
Migration table created successfully.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table

这样数据库就建立好了,在mysql里面就能看到migrations、password_resets、users三个表,就可以只用Laravel自带的用户系统。

Laravel 学习(二)数据库建立与迁移

@玛酷猫10 年前

04/8
13:44
计算机

Laravel 学习(一)安装

写在前面:话说自从换工作以来这两年,除了能够使用flash做广告条新技能get外,其他方面一直原地踏步,还在吃好几年前的老本,尤其是参加了一次技术活动后,更感觉自己脱钩严重,技术群里讨论只有听别人说的份,各种术语理解不能,插不上嘴。趁着最近有点时间,提升下自己好了。这两年Laravel异常火热,以前用过CI和thinkphp做过开发,学习起来难度应该不会太大,就拿这个下手好了。

开始之前,首先去官网转了圈,对于英文苦手的我来说这个完全理解不能,度娘了下,找到中文的手册,顺道找了份教程,大概看了遍,有个印象。网上各种安装教程都是在linux环境下,由于本机开发环境是IIS,各种懒病发作不想在装个虚拟器配个linux,在度娘的指引下,找到一份iis下安装的教程,万事俱备,下面开搞(开搞以后才知道各种坑)。

Laravel最新版本是5,环境需求php >=5.4,由于之前开发环境一直是php-5.2.17和php-5.3.8,第一件事就是去php官网下个最新的稳定版php,目前最新的版本号是5.6.7,借助IIS一个强大的官方插件php manager for iis,可以很轻松的在各个版本php之间切换,修改配置,启用禁用插件都相当方便,点点鼠标就行,正适合我这种懒人。

laravel框架使用composer来管理代码依赖性,去官网下载composer的windows版本,依照教程安装,各种失败,度娘了下才知道还需要准备梯子翻越伟大的墙,这个对于IT屌丝来说不是问题,祭出屌丝专用梯子搬瓦工(具体教程可自行度娘,30块钱不到一年,)顺利安装完成。

接着安装Laravel,按着教程从Github上下载最新的版本,解压,进入命令行,composer install,漫长等待后,出来一堆代码,虽然完全看不懂,但是各种errer,各种failed还是看得懂的,总之一句话,安装失败。不知道是环境配置缺少什么还是梯子不好使,试过几次后果断放弃直接安装方法。好在国内有同仁制作了完整安装包,直接下来就能用的,方便至极。

剩下的就简单了,解压放到工作环境中,新建站点,指向Laravel的public目录,直接访问,简洁的”Laravel 5  When there is no desire, all things are at peace. – Laozi“引入眼帘。

最后,借助IIS另一个实用的官方插件URL Rewrite,导入根目录下的.htaccess文件,伪静态也搞定。

自此Laravel安装完成。

Laravel 学习(一)安装

@玛酷猫17 年前

08/6
13:30
Linux

redhat9下安装 MySQL5+Apache2+php5[转]

(正在研究LINUX,寻找了点资料,大家一起分享。)

准备工作: 下载安装文件mysql-standard-5.0.27-linux-i686.tar.gz、httpd-2.2.3.tar.gz、php-5.2.0.tar.gz ,并把它们放在/usr/local/src/ 文件夹里。
一、安装MySQL5
  
1、 在 /usr/local/  里建立 mysql 文件夹。
   # cd /usr/local
   # mkdir mysql
 
2、在 mysql 文件夹里解压文件( 这样解压出的文件夹就是当前文件夹下面 )。
   # cd mysql
   # tar -zxfz  /usr/local/src/mysql-standard-5.0.27-linux-i686.tar.gz
   # ln -s mysql mysql-standard-5.0.27-linux-i686 
//为文件夹 mysql-standard-5.0.27-linux-i686 建立快捷方式。
 
3、# groupadd mysql   
// 建立mysql组
   # useradd mysql -g mysql 
//建立mysql用户并且加入到mysql组中 
 
4、# cp /usr/local/mysql/support-files/my-medium.cnf /etc/my.cnf  
//在 support-files目录下有4个模版文件,我们选择其中一个座位Mysql的配置文件,覆盖/etc/my.cnf(系统默认的配置,其中设置了性能参数和Mysql的一些路径参数)。
 
5、# ./scripts/mysql_install_db –user=mysql    
//初试化表并且规定用mysql用户来访问。初始化表以后就开始给mysql和root用户设定访问权限。
 
6、# chown -R root .    
 //设定root能访问/usr/local/mysql ( 注意root 后面有一个空格和点)。
 
7、 # chown -R mysql data     
//设定mysql用户能访问/usr/local/mysql/data ,里面存的是mysql的数据库文件.这个目录是在/etc/my.cnf中有配置,在mysql_install_db时产生。
 
8、# chown -R mysql data/.    
//设定mysql用户能访问/usr/local/mysql/data/mysql下的所有文件
 
9、# chgrp -R mysql .      
//设定mysql组能够访问/usr/local/mysql
 
10、# /usr/local/mysql/bin/mysqld_safe –user=mysql &     
//运行mysql,如果没有问题的话,应该会出现类似这样的提示:[1] 42264
   # Starting mysqld daemon with databases from /usr/local/mysql/var    
//如果出现 mysql ended这样的语句,表示Mysql没有正常启动,你可以到log中查找问题,Log文件的通常在/etc/my.cnf中配置。大多数问题是权限设置不正确引起的。
 
11、# /usr/local/mysql/bin/mysqladmin -u root password yourpassword    
//默认安装密码为空,为了安全你必须马上修改.
 
12、# cp support-files/mysql.server /etc/rc.d/init.d/mysqld     
//copy编译目录的一个脚本
   # chmod 700 /etc/init.d/mysqld    
//设置使mysql每次启动都能自动运行
   # chkconfig –add mysqld
   # chkconfig –level 345 mysqld on
 
13、# service mysqld start    
//启动mysqld服务
   # netstat -atln     
//查看3306端口是否打开。要注意在防火墙中开放该端口。
  
二、安装apache2
  
1、解压文件
   # cd /usr/local 
   # tar -zxvf /usr/local/srchttpd-2.2.3.tar.gz
 
2、安装
   # cd httpd-2.2.3
   # ./configure –prefix=/usr/local/apache –enable-track-vars –enable-cgi –enable-so –enable-rewrite –enable-mods-shared=all –with-config-file-path=/usr/local/apache/conf
   # make
   # make install
 
3、启动
   # /usr/local/apache/bin/apachectl start
   # netstat -utl   //并检查是否启动
 
4、把apache加入开机启动,把下面这一行加入到/etc/rc.local中。
   /usr/local/apache/bin/apachectl start
  
三、安装php5
  
请先安装libxml,2.6.10以上版本的。

1、# cd /usr/local
   # tar -zvxf /usr/local/src/php-5.2.0.tar.gz 
   # cd php-5.2.0
 
2、# ./configure –prefix=/usr/local/php –with-mysql –with-apxs2=/usr/local/apache/bin/apxs
–enable-trace-vars –with-zlib-dir=/soft/zlib-1.2.3/
 
3、 # make; make install
 
4、拷贝PHP配置文件php.ini:
   # cp ../php5.2.0/php.ini-dist /usr/local/php/lib/php.ini
 
5、添加php类型
   # vi /usr/local/apache/conf/httpd.conf
   AddType application/x-httpd-php .php (230行左右)
 
6、重启
   # /usr/local/apache/bin/apachectl stop
   # /usr/local/apache/bin/apachectl start
 
7、测试
   # cd /usr/local/apache/htdocs
   # vi test.php
   <?php
      phpinfo();
   ?>
最后输入 http://您的地址/test.php 测试

redhat9下安装 MySQL5+Apache2+php5[转]