分类: 技术

  • magento2迁移,密码修改,主题样式加载等问题【实操手册】

    magento2 确实是牛的系统,框架板块的灵活性和强大是毋庸置疑的,其安装,迁移和维护多少是需要点技术知识的,但都说熟能生巧,知道套路,会百度,积累,询问和尝试,总归能搞定的,那么废话不多说,以下对于magento2的整站迁移做归纳总结:

    运行环境:linux +nginx+mysql的基本配置,PHP7.2

    服务器:阿里云ECS

    操作平台:宝塔,关于服务环境和宝塔的搭建,这里具体就不详细讲了

    一,打包好数据库和项目文件,数据库是SQL格式,可直接从PHPMYADMIN中导出

    二,上传数据库文件和项目文件,到你要迁移的服务器中(先可以不用修改数据库和项目文件的内容)

    三,配置好域名和数据库的修改

    1,域名如果要修改,可在数据库文件中找到文件:mgck_core_config_data ,可直接修改或语句执行修改你的新域名,记得域名后面加 “/”

    2,可解决CSS样式不加载的问题

    a,执行数据库命令:

    insert mgck_core_config_data (config_id, scope, scope_id, path, value) values (null, ‘default’, 0, ‘dev/static/sign’, 0);

    b,在SSH导向CD magento2根目录运行CLI命令:

    php bin/magento setup:static-content:deploy -f

    php bin/magento indexer:reindex

    c,删除magento2跟文件夹下的var目录:

    rm -rf var/*

    3,对照修改数据库名和密码,连接站点,可在app/etc目录下的文件:env.php 进行修改即可;

    4,如果修改密码:找到项目目录下app/etc/env.php,找到crypt对应的key参数

    连接mysql客户端选择当前使用的数据库。

    执行以下sql语句,参数替换为你的参数

    UPDATE admin_user SET password = CONCAT(SHA2(‘xxxxxxxYourNewPassword’, 256), ‘:xxxxxxx:1’) WHERE username = ‘admin’;

    参数说明:

     “xxxxxxx” 为第一步的key对应的参数

    “YourNewPassword” 为新密码

    “admin” 为忘记密码的用户名,可根据实际所需更改

    执行成功后清理magento缓存

    三,宝塔用WWW用户进行执行,如果是ROOT用户,则需要切换到www执行,如下:

    1,root用户角色进入,执行命令:vim /etc/passwd,打开文件,找到www用户,修改内容www:x:1000:1000::/home/www:/bin/bash ,i编辑,ecs退出编辑,然后保存 :wq ;强力保存 :wq!

    2,执行命令:线上环境恢复:vim ~/.bashrc ,打开保存

    3,执行命令:alias www=’cd /www/wwwroot/ && sudo su – www -s /bin/bash’

    4,执行命令:source ~/.bashrc

    5,执行命令:root用户转www用户,命令:www,直接输入即可调换用户,下一次需要执行命令: su www

    6,还有不能禁用一些函数比如syslog,openlog,exec,system,syformlink,proc_open,putenv函数,否则会提示错误,在php.ini中修改

    7,注意内存大小,调整到512M,甚至1024,如运行下列命令时的要求:php bin/magento deploy:mode:set production

    8,有错误问题请详细查看,或查看错误日志:/www/wwwroot/目录/var/log

    四,运行以下命令更新,可以不用sudo

    sudo php bin/magento maintenance:enable
    sudo php bin/magento cache:clean
    sudo php bin/magento setup:upgrade
    sudo php bin/magento setup:di:compile
    sudo php bin/magento bms_advancedstock:flush_stock_index
    sudo php bin/magento indexer:reindex
    sudo php bin/magento setup:static-content:deploy 部署magento的静态内容
    sudo php bin/magento cache:clean
    sudo php bin/magento deploy:mode:set production
    sudo php bin/magento maintenance:disable

    五,完成,打开站点

    其中,宝塔中伪静态处理:

    location / {
    index index.HTML index.php; ## Allow a static html file to be shown first
    try_files $uri $uri/ @handler;
    expires 30d;
    }

    location /var/export/ { ## Allow admins only to view export folder
    auth_basic “Restricted”; ## Message shown in login window
    auth_basic_user_file htpasswd; ## See /etc/nginx/htpassword
    autoindex on;
    }
    location /. { ## Disable .htaccess and other hidden files
    return 404;
    }

    location @handler { ## Magento uses a common front handler
    rewrite / /index.php;
    }

    location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
    rewrite ^(.*.php)/ $1 last;
    }

  • Magento搬家、换域名、重新安装教程

    范例:从http://www.youdomain.com 迁移到http://www.newsite.com。

    • 将原来网站文件中的var文件中的cache和session文件删除,将media中的缓存文件删除。然后将所有文件制作成一个压缩包,以减少文件体积,方便转移。
    • 将压缩包转移到新的服务器域名指向的文件夹,解压。

    一、首先要通过phpMyAdmin备份整个magento的数据库。备份数据并且存为.SQL.

    二、接着打开你的备份文件(.SQL),查找并且替换所有的 “www.youdomain.com” 到“www.newsite.com”. 必须在导入数据之前完成,不然新的MAGENTO将会全部瘫痪。

    三、 接着别关闭你的备份文件(.SQL),还有重要一步就是必须强制关闭相关的“数据库关键字的关系”。

    请拷贝下面代码放在你的SQL代码的顶部:

    SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT;
    SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS;
    SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION;
    SET NAMES utf8;
    SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
    SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
    SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
    SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0;

    接着将下面的代码放在你的SQL代码的底部:

    SET SQL_MODE=@OLD_SQL_MODE;
    SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
    SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
    SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT;
    SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS;
    SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION;
    SET SQL_NOTES=@OLD_SQL_NOTES;

    四、接下来,保存后压缩你的数据库(.SQL)文件,结尾为ZIP格式。因为我的原SQL文件大约8MB,但是压缩之后只有500KB,这样可 以大大加速上传的时间。记住,请用PHPMYADMIN上传。如果数据库比较大,你可以修改服务器运行时间。

    五、把原网站所以文件拷贝到你要迁移的服务器上。

    六、现在你需要打开htdocs/app/etc/local.xml并且修改其中的数据库连接到新服务器的数据库(对应www.newsite.com).保存你的修改。现在你的magento应该可以工作了。

    Magento搬家、换域名、重新安装教程
    Magento搬家、换域名、重新安装教程

    七、最后还有一样事情你需要做,那就是修改 .htaccess文件. 如果你迁移是从一个服务器到另外一个服务器,而且所有的绝对路径是相同的,你不需要做任何事情。
    但是如果你是从子文件夹http://www.youdomain.com/store/移动出来,你需要修改.htaccess 中 “RewriteBase/magento/” 部分。并且搜索替换SQL中相关的部分,例如“http://www.youdomain.com/store”换成“http: //www.newsite.com/” 。

    • 安装结束后,进入后台去刷新下缓存和索引管理。
    • 在前台检查是否有异样。如果某些图片显示不正常,检查是否使用了固定的链接,因为域名更换,引起图片无效。
    • 如果修改了域名, 则还需要修改magento数据库,core_config_data表中的path为web/unsecure/base_url和web /secure/base_url的内容,为你网站的新域名,注意域名后面的“/”。更换网站完整域名+/  http://www.abc.com/
    • 登录进入Magento后台, 进入system 的Cache management和index management刷新一下缓存, 并且重建索引.

    注意:

    如果恢复SQL的过程中出现如下错误:

    Mysql查询错误
    查询语句:DROP TABLE IF EXISTS `mg_admin_role`
    错误信息:Cannot delete or update a parent row: a foreign key constraint fails

    就是因为MySQL外键约束导致mysql还原出错,可以在

    在恢复数据之前运行下面语句,取消外键检查

    SET FOREIGN_KEY_CHECKS = 0;

    恢复之后再运行:

    SET FOREIGN_KEY_CHECKS = 1;

    即可。

    在新空间创建新的数据库,导入备份的数据文件。如果导不进去的是因为magento的数据库使用了外键约束,通过phpmyadmin导入的时候会报错,在导出的sql文件上加一行

    1SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;

  • 词云制作没那么难,Python 10 行代码就实现了!

    写在前面

    想必大家有一个问题。什么是词云呢?

    词云又叫名字云,是对文本数据中出现频率较高的“关键词”在视觉上的突出呈现,形成关键词的渲染形成类似云一样的彩色图片,从而一眼就可以领略文本数据的主要表达意思。

    网页上有许多词云的效果图:

    而且,目前有许多制作词云的工具:

    但是作为一个学习Python的程序员来说,我更喜欢通过自己的编程去解决问题。

    而且用Python制作词云只需十行代码就行了哦~

    一起来看看吧!

    代码块

    import matplotlib.pyplot as plt

    from wordcloud import WordCloud

    import jieba

    text_from_file_with_apath = open(‘/Users/hecom/23tips.txt’).read()

    wordlist_after_jieba = jieba.cut(text_from_file_with_apath, cut_all = True)

    wl_space_split = ” “.join(wordlist_after_jieba)

    my_wordcloud = WordCloud().generate(wl_space_split)

    plt.imshow(my_wordcloud)

    plt.axis(“off”)

    plt.show()

    代码效果图:

    下面咱们解析一下代码块:

    1~3 行分别导入了画图的库,词云生成库和jieba的分词库;

    4 行是读取本地的文件,代码中使用的文本是本公众号中的《老曹眼中研发管理二三事》。

    5~6 行使用jieba进行分词,并对分词的结果以空格隔开;

    7行对分词后的文本生成词云;

    8~10行用pyplot展示词云图。

    这是我喜欢python的一个原因吧,简洁明快。

    当然,这只是一个简单得不能再简单得编程,实现的效果也非常简单

    但是Python是一门开源的语言,这时候就体现出开源的特性了,任何人都能对一个项目加以修改,使项目不断的完善。

    Github上有许多开源的项目,小编找到一个做词云的项目,链接如下:

    https://github.com/amueller/word_cloud

    咱们可以直接进入wordcloud.py 源码进行字体,词云效果进行修改。

    源码解析:

    wordcloud.py总共不过600行,其间有着大量的注释,读起来很方便。其中用到了较多的库,常见的random,os,sys,re(正则)和可爱的numpy,还采用了PIL绘图,估计一些人又会遇到安装PIL的那些坑.

    生产词云的原理其实并不复杂,大体分成5步:

    1. 对文本数据进行分词,也是众多NLP文本处理的第一步,对于wordcloud中的process_text()方法,主要是停词的处理
    2. 计算每个词在文本中出现的频率,生成一个哈希表。词频计算相当于各种分布式计算平台的第一案例wordcount, 和各种语言的hello world 程序具有相同的地位了,呵呵。
    3. 根据词频的数值按比例生成一个图片的布局,类IntegralOccupancyMap 是该词云的算法所在,是词云的数据可视化方式的核心。
    4. 将词按对应的词频在词云布局图上生成图片,核心方法是generate_from_frequencies,不论是generate()还是generate_from_text()都最终到generate_from_frequencies
    5. 完成词云上各词的着色,默认是随机着色

    词语的各种增强功能大都可以通过wordcloud的构造函数实现,里面提供了22个参数,还可以自行扩展。

    效果图:

    写在最后

    小伙伴看了文章自己可以动手操作操作哦,是Python一个十分简单的项目呢。

  • 果粉也用安卓!MacBook连接安卓机最好的工具

    果粉也用安卓!MacBook连接安卓机最好的工具

    尽管iPhone很出色,然而iPhone在续航、快充、5G、本土化功能等方面的短板,让很多果粉也换用了安卓手机,或者将安卓作为备机。然而,很多果粉都只有MacBook,毕竟MacBook目前仍是最出色的轻薄本之一,在macOS上如何连接安卓机?macOS固然支持安卓的MTP模式,但体验其实并不好,更多朋友会选择其他一些第三方方案。

    之前锤子曾经推出过一款macOS连接安卓机的软件“HandShaker”,不过它已经久未更新了。有没有其他工具?今天就来给大家推介一款“OpenMTP”,这可能是当前macOS连接安卓机最好的工具了!

    OpenMTP:https://openmtp.ganeshrvel.com/

    OpenMTP是一款来自国外的软件。首先它的一大良心之处,就在于它是完全开源且免费的。如果你是一名开发者,也可以点击下面的链接,进入OpenMTP的GitHub开源页面查看其源代码。

    OpenMTP主界面

    OpenMTP GitHub页面:https://github.com/ganeshrvel/openmtp

    OpenMTP的使用非常简单,用dmg镜像载入安装后,开启软件,然后通过USB将安卓机连接到MacBook之类的macOS电脑上,OpenMTP就可以呈现安卓机当中的内容了。OpenMTP能够支持安卓机的内置存储空间和SD卡,也支持大于4GB的文件,兼容性不俗。

    OpenMTP的操作也没有什么短板。它支持最基本的拖曳传输,无论想把文件从安卓传输到Mac中,还是反过来,直接拖曳就可以完成;另外,它也支持macOS众多快捷键,例如常见的command()+c/v复制粘贴等等,用起来没有什么门槛。

    OpenMTP传输过程

    OpenMTP的界面简简单单,支持列表和图标视图,并且支持多种文件排序方式。总体而言,它的体验是和macOS的Finder比较接近的,传输速度也没有什么掉链子的地方,完全可以担当起Mac和安卓之间数据传输的桥梁。

    简而言之,这是一款非常实用的工具。macOS原生对安卓机的连接有不稳定等问题,用OpenMTP可以很好地弥补这方面的缺陷。如果你同时是Mac和安卓机的用户,这款OpenMTP绝不容错过了。

    资源下载地址:https://github.com/ganeshrvel/openmtp

  • 如何将WordPress网站转换为APP移动应用程序

    如何将WordPress网站转换为APP移动应用程序

    wordpress怎么生成app

    虽然现在大部分的wordpress主题都是完美自适应,无论在平板上还是手机上浏览都没有任何的影响。但是就目前访客的习惯或者体验上来讲,一个完整的APP显然更具吸引力。而对于wordpress博主/站长来讲,APP的一些推送功能,无疑会增加网站的流量或者说提示访客的粘性,这些都是非常重要的。所以学会如何将wordpress网站转换成APP是很有必要的。

    接下来,我们将分享几个可以将你的网站快速生成APP的wordpress插件。

    1. AppPresser

    AppPresser是创建与WordPress集成的iOS和Android移动应用程序的最佳方式之一。您可以使用现有页面组合应用程序,并创建新的移动友好菜单。

    此外,AppPresser还具有以WordPress定制器为模型的可视化编辑器。这意味着如果您已经习惯了内容管理系统(CMS),那么这些操作将变得非常简单。此外,您还可以使用实时预览功能查看应用的外观,该功能可实时显示每个变化。

    主要特征:

    允许您为您的网站设置iOS和Android应用程序。

    与WordPress网站完美集成。

    使您可以使用自定义程序样式编辑器来创建应用程序。

    价格: 起价为每月19美元

    2. Super Progressive Web Apps

    Super Progressive Web Apps(PWA)是一款免费将wordpress网站生成APP的插件。实用PWA这款插件前,要确保您的网站是完全自响应。否则,访客将无法获得最佳体验。当有人从移动设备访问时,Super Progressive Web Apps插件会 向您的网站添加“添加到主屏幕” 通知。如果他们点击它,该插件将在他们的主屏幕上设置一个APP应用程序的按钮,访客可以该按钮直接访问您的网站。此外,该插件还将设置一个简单的LOGO图标。

    主要特征:

    为您的网站创建PWA。

    为您的网站应用程序设置自定义图标和启动画面。

    用户可以快速将您网站的PWA添加到主屏幕。

    价格: 免费

    3. WPMobile.app

    WPMobile.app可以用最简单的方式创建网站APP应用程序,虽然该插件在自定义应用程序方面并不是最好的,但它确实有很多其他实用的功能,例如,您可以在发布之前测试您的移动应用程序,确保没有任何问题之后再发布。

    该插件还自带完美的的搜索和社交分享功能。而且还提供了用户的一些数据统计分析,如果您想认真考虑改善用户体验,这是非常宝贵的。

    主要特征:

    允许您在发布前测试您的网站应用程序。

    发布新内容时提供自动更新。

    提供向您的应用添加搜索功能和社交分享的功能。

    允许访问有关您的应用用户的分析。

    价格: 单个Android应用程序的终身许可证起价为56美元

    4. AppyPie

    AppyPie与上面谈到的网站生成APP插件有很大的不同。它既不是用于WordPress插件或第三方应用程序。相反,它是一个功能齐全的应用程序构建器。有了它,您可以创建一个网站应用程序,甚至可以根据需要处理更复杂的项目。

    此服务包括Android和iOS应用程序构建器,以及将现有网站转换为应用程序的工具。对于您创建的任何应用,您可以设置订阅,推送通知,联系表单,社交媒体链接和共享按钮等。添加所有这些功能很简单,因为AppyPie具有拖放式应用程序构建器,包括实时预览功能。

    最后,AppyPie为常见的项目类型包含了很多应用程序“模板”。例如,如果您想创建餐厅,房地产甚至播客应用程序,这是一个很好的选择。

    主要特征:

    使您能够从头开始构建自定义Android和iOS应用程序,或使用您的站点作为模板。

    允许您使用拖放构建器添加功能。

    允许您从几种类型的应用程序模板中进行选择,以加快“开发”过程。

    价格: 有一个功能有限的免费计划,高级选项起价为每个应用每月209美元

  • Magento模板安装详细过程

    Magento模板安装详细过程

    第一种方法是通过magento connect (magento连接器)功能来安装magento主题模板。详细步骤如下:

    1.首先你要到magento官网找到一个免费的magento主题(收费的要交钱后才提供给你extension key),找到后那你会看到在主题图片下方有个Get Extension Key按钮,点击Get Extension Key 并勾选“By checking this box I agree to the extension license agreement.”复选框就会得到一个extension key,复制key如图:

    magento themes

    2. 通过magento后台->系统(system)->(magento连接)magento connect->(magento连接管理)magento connect manager打开并用管理用户登录,然后把你刚复制的extinction key 拷贝到Paste extension key to install 后面的输入框中,点击install按钮,如图:

    3. 如果你的extinction key 没过期的话,稍等片刻你会看到“Theme successfully installed”信息展示在下面的信息框中,这表明你已经安装成功了。接着你必须到后台->系统(system)->(配置)Configuration->(设计)Design->(主题)Themes,在default一栏填写你安装成功的主题名称,这里填 modern。如图:

    4.如果你不清楚你的magento主题名称,你可以到你网站的目录\app\design\frontend\default下查看你主题文件夹的名称。填写好刷新缓存,前台即可显示为你安装的magento主题。

    第二种方法是直接通过文件夹进行安装。详细步骤如下:

    注意区分“主题包”和“主题文件”这两个概念。我们所使用的主题在“主题文件”中,“主题包”中可以含有多个主题文件

    1. 首先我们来看下magento主题文件的存放规则

    主题文件路径一般为

    app/design/frontend/主题包名字/主题文件名字/layout+locael+template

    skin/frontend/主题包名字/主题文件名字/css+images+js

    2.当我们新安装好一个magento的时候,magento使用default主题包中的default主题文件路径如下

    app/design/frontend/default/default

    skin/frontend/default/default

    红色部分为主题包的名字“default”

    蓝色部分为主题文件夹的名字“default”

    因为default主题是magento的默认设置,所以在后台的设置中留空就是设置为default

    3.我们来看后台system—>configration—->general—>design

    若要使用的主题文件路径如下,后台的设置便如下图所示

    app/design/frontend/default/blank

    skin/frontend/default/blank

    4.当你购买到一个新的magento主题的时候,假设它的主题包的名字是blank,他的文件路径可能是如下的样子,那你应该这样设置,如图:

    app/design/frontend/blank/theme037

    skin/frontend/blank/theme037

    后台的设置的时候,主题文件包的名字是“blank”,主题文件夹的名字是“theme037”

  • 麦进斗 Magento 设置多站点、多域名、多语言、多货币

    麦进斗 Magento 设置多站点、多域名、多语言、多货币

    1、登录后台system->manage stores
    多站点
    选择create website:

    进入:

    填写完整后,保存,再去该website下新建store和store view
    store新建:

    2、store下面可以新建多个store view(即多语言设置),Code的值是展示view的关键所在
    每个view代表着一种语言,所以建立多个view时,需要去下载安装语言包,magento-community

    3、多个网站,重复上面步骤即可。
    4、多域名设置
    system->confirguration

    5、然后在选择,GENERAL标签下的Web:

    6、取消use default(或者 use website)前面的勾, 在Unsecure和Secure的base url中输入你已经拥有的域名
    点击保存。
    7、多域名设置的最后一步,修改项目根木的 .htaccess文件:

    打开文件在最后加入:

    SetEnvIf Host ^xncp.mez100.de.cn    MAGE_RUN_CODE=de   /* Store or website code 这里的code新建store view时的code输入框的值*/
    SetEnvIf Host ^xncp.mez100.de.cn    MAGE_RUN_TYPE=website  /* Run store or run website */
    

    8、多货币的设置
    view或website设置多货币
    再选择下方的currency Setup:

    依次设置基础货币、默认货币、所允许的货币
    在Allowed Currencies选择多个值后,保存,实现多货币的设置
    在去设置货币汇率。这个如果不设置的话,在前台不会出现货币转换的选项:

    这里可以设置货币的汇率以及货币的符号
    货币汇率:

    货币符号:

    设置好后,保存,在前台就可以看见货币转为的选项了。
    下面还有一种多域名的做法(又称二级目录)
    假设我们的网站现在有个vip的站点(只有允许vip用户访问)
    1、登录后台system->configuration,选择对应的website或store view ,选择左侧的 web 标签:


    注意:{{secure_base_url}}/de有个斜线,设置的时候不要漏掉。
    按上图配置好后,点击保存。
    2、回到项目的根目录中,新建一个de的文件夹(这里的de为你在后台配置web下Base Link URL后面追加的那个de),创建如下:


    将更目录的index.php的内容copy到de文件下的inde.php,文件.htaccess也一样从根目录的.htaccess 拷贝到de文件夹下的.htaccess
    3、修改de文件下的index.php;

    <?php
    /**
     * Magento
     *
     * NOTICE OF LICENSE
     *
     * This source file is subject to the Open Software License (OSL 3.0)
     * that is bundled with this package in the file LICENSE.txt.
     * It is also available through the world-wide-web at this URL:
     * http://opensource.org/licenses/osl-3.0.php
     * If you did not receive a copy of the license and are unable to
     * obtain it through the world-wide-web, please send an email
     * to license@magentocommerce.com so we can send you a copy immediately.
     *
     * DISCLAIMER
     *
     * Do not edit or add to this file if you wish to upgrade Magento to newer
     * versions in the future. If you wish to customize Magento for your
     * needs please refer to http://www.magentocommerce.com for more information.
     *
     * @category   Mage
     * @package    Mage
     * @copyright  Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
     * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
     */
    
    if (version_compare(phpversion(), '5.2.0', '<')===true) {
        echo  '<div style="font:12px/1.35em arial, helvetica, sans-serif;"><div style="margin:0 0 25px 0; border-bottom:1px solid #ccc;"><h3 style="margin:0; font-size:1.7em; font-weight:normal; text-transform:none; text-align:left; color:#2f2f2f;">Whoops, it looks like you have an invalid PHP version.</h3></div><p>Magento supports PHP 5.2.0 or newer. <a href="http://www.magentocommerce.com/install" target="">Find out</a> how to install</a> Magento using PHP-CGI as a work-around.</p></div>';
        exit;
    }
    
    /**
     * Error reporting
     */
    error_reporting(E_ALL | E_STRICT);
    
    /**
     * Compilation includes configuration file
     */
    $compilerConfig = '../includes/config.php';
    if (file_exists($compilerConfig)) {
        include $compilerConfig;
    }
    
    $mageFilename = '../app/Mage.php';
    $maintenanceFile = '../maintenance.flag';
    
    if (!file_exists($mageFilename)) {
        if (is_dir('downloader')) {
            header("Location: downloader");
        } else {
            echo $mageFilename." was not found";
        }
        exit;
    }
    
    if (file_exists($maintenanceFile)) {
        include_once dirname(__FILE__) . '/errors/503.php';
        exit;
    }
    
    require_once $mageFilename;
    
    #Varien_Profiler::enable();
    
    if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) {
        Mage::setIsDeveloperMode(true);
    }
    
    #ini_set('display_errors', 1);
    
    umask(0);
    
    /* Store or website code */
    $mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : '';
    
    /* Run store or run website */
    $mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store';
    
    /*de为 website or store view code*/
    /*如果该站点为website的话,将store改为wensite即可*/
    Mage::run('de', 'store');
    

    4、然后在浏览器中输入www.xample.com/de就可以访问相应的store view或website了

  • Themeforest购买主题模板的详细步骤

    Themeforest购买主题模板的详细步骤

    Themeforest是全球最大的WordPress主题服务商。一共有4万多个wordpress主题,几乎囊括了所有行业,里面销量最高的Avada主题,就算你不会写代码,也可以用它搭建出世界级的网站,今天一灯会从以下3个方面讲解,分别是:

    1. 什么是themeforest?
    2. 如何在themeforest找到高质量主题?
    3. 如何在themeforest购买Avada主题?

    1、什么是themeforest?

    themeforest

    themeforest是一家澳大利亚公司,成立于2008年,主攻wordPress主题。

    截止到今天,themeforest一共发布了47729个wordpress主题,全部由专业人员开发,不仅功能强大,而且漂亮美观,通常会被更新维护的非常好,并提供强大的售后支持,主题本身几乎无缺陷,是外贸建站的秘密武器。

    同时,themeforest也是envato大家庭里的一员,其它成员还包括codecanyon,一个主攻wp插件的网站。顺便说下,themeforest的wordpress主题不是免费的,之所以收费也保证了较高的质量和功能,价格在30~60美元,一次性收费,终身使用,对应一个网站。

    2、如何在themeforest找到高质量主题?

    themeforest有很多筛选功能,可以帮助你找到你想要的那个主题。

    点击wordpress会出现下拉菜单,横跨18个类别,包括企业主题,博客主题,创意主题,电商主题等等,选中并进入类别后,还可以进行高级搜索,有6个类别可供选择,如下图所示。

    themeforest主题筛选

    也可以用左边的筛选系统来选择主题,如下图所示。

    主题筛选选项

    如果你没时间去层层筛选,可以直接点击themeforest的畅销页面找到销量最高的主题,并依靠以下4个标准来做二次筛选,如果你不确定该买哪个主题, 建议去畅销页面,因为这些主题已经销售了几十万次。

    • 销量:销量高的主题代表用户满意度高
    • 评论:靠评论来判断主题模板是否靠谱
    • 评分:5星评分是最好的
    • 最后更新时间:长时间不更新的主题有安全漏洞隐患

    可以负责地说,销量高的主题无论是外观还是功能都遥遥领先销量低的主题。同时,开发者也会有资金支持一直更新和完善主题,并及时处理用户使用过程中所遇到的问题。

    下面就让我们来看看themeforest上最畅销的wordpress主题有哪些?

    Avada(213,320 Sales)

    avada

    价格:$ 60 | 直达链接

    Enfold(88,833 Sales)

    enfold

    价格:$ 60 | 直达链接

    Betheme(47,263 Sales)

    betheme

    价格:$ 59 | 直达链接

    uDesign(45,083 Sales)

    udesign

    价格:$ 59 | 直达链接

    The7(36,380 Sales)

    the7

    价格:$ 59 | 直达链接

    当然,还有其它很多地方可以购买wordpress主题,比较知名的有studiopress,mojothemes,creativemarket,wootheme和elegantthemes,但我觉得都没有themeforest性价比高。

    3、如何在themeforest购买Avada主题?

    1,首先先进入产品页面,点击右边的add to cart。

    avada产品页面

    2,结账

    avada结账
    avada付款

    3,由于是新用户,themeforest会提示你先注册账号,填写你的姓名,邮箱后点击next会提示你填写用户名和密码。填完后点击谷歌机器人验证并请勾选左下角的I have read,最后点击creat a account & continue。

    themeforest新用户注册
    谷歌机器人验证

    4,点击上一步的creat a account & continue后会跳转到下面的页面,填写你的账单信息后点击save and continue。

    avada付款信息

    然后选择支付方式,信用卡和paypal有2美元的手续费,在这一灯选择的是信用卡付款。

    avada付款方式
    avada信用卡付款

    5,点击上一步的make payment后就完成购买了,紧接着会提示你去downloads page下载你所购买的主题,下载按钮有下拉菜单。你可以选择下载全部文件或是只下载主题的安装文件,全部文件里包含了demo数据这些,建议下载第二个选项WordPress file only。

    avada购买成功
    avada主题下载

    总结

    主题安装文件下载完,接下来就是安装Avada主题和激活Avada主题。顺便说下,Avada主题或Themeforest上的任何一个wordpress主题都是一次性付费,终身使用,无限制下载,终身享受主题更新和售后服务,但只对应一个网站域名。

    如果你暂时不打算购买,可以去wordpress官方下载免费wordpress主题,不过wordpress免费主题的外观及功能和收费的差距较大。

  • 订阅支付解决方案:Laravel Cashier(Braintree)

    订阅支付解决方案:Laravel Cashier(Braintree)

    简介

    Laravel Cashier Braintree 为通过 Braintree 实现订阅支付服务提供了一个优雅的流式接口。它封装了几乎所有你恐惧编写的样板化的订阅支付代码。除了基本的订阅管理外,Cashier 还支持处理优惠券、订阅升级/替换、订阅「数量」、取消宽限期,甚至生成 PDF 发票。

    注:该文档适用于 Cashier 与 Braintree 的集成,如果你在使用 Stripe,请参考 Stripe 集成文档。

    注:如果你只需要一次性支付,并不提供订阅,就不应该使用 Cashier,而是直接使用 Braintree SDK。

    注意事项

    对于绝大多数操作而言,Cashier 的 Stripe 和 Braintree 实现功能都是一样的,两个服务都提供了通过信用卡进行订阅支付的功能,Braintree 还支持通过 Paypal 进行支付。不过,Braintree 缺少了一些 Stripe 所支持的功能,在决定使用 Stripe 还是 Braintree 之前,需要权衡以下因素:

    • Braintree 支持 Paypal 而 Stripe 不支持;
    • Braintree 不支持在订阅上调用 increment 和 decrement 方法,这是 Braintree 的局限,而不是 Cashier 的;
    • Braintree 不支持基于百分比的折扣,这也是 Braintree 的局限,而不是 Cashier 的。

    安装

    首先,需要通过 Composer 安装适用于 Braintree 的 Cashier 扩展包:1 composer require laravel/cashier-braintree

    配置

    计划信用优惠券

    在使用基于 Braintree 的 Cashier 之前,需要在 Braintree 的控制面板中定义一个 plan-credit 折扣,这个折扣将会用于从年到月或者从月到年支付的优惠额度比例分配。

    配置在 Braintree 控制面板中的这个折扣值可以是你希望的任何值,Cashier 将会在每次使用优惠券的时候通过自定义的值来重写这个默认定义的值。该优惠券之所以是必须的是因为 Braintree 不支持本地根据订阅时长进行优惠额度的按比例分配。

    数据库迁移

    使用 Cashier 之前,需要准备好数据库。我们需要添加额外的字段到 users 表并创建一个新的 subscriptions 表用于存放所有用户订阅:

    Schema::table(‘users’, function ($table) {
    $table->string(‘braintree_id’)->nullable();
    $table->string(‘paypal_email’)->nullable();
    $table->string(‘card_brand’)->nullable();
    $table->string(‘card_last_four’)->nullable();
    $table->timestamp(‘trial_ends_at’)->nullable();
    });

    Schema::create(‘subscriptions’, function ($table) {
    $table->increments(‘id’);
    $table->integer(‘user_id’);
    $table->string(‘name’);
    $table->string(‘braintree_id’);
    $table->string(‘braintree_plan’);
    $table->integer(‘quantity’);
    $table->timestamp(‘trial_ends_at’)->nullable();
    $table->timestamp(‘ends_at’)->nullable();
    $table->timestamps();
    });

    迁移被创建之后,只需要执行 Artisan 命令 migrate 即可。

    Billable 模型

    接下来,添加 Billable Trait 到模型定义:1

    use Laravel\Cashier\Billable;

    2

    ​

    3

    class User extends Authenticatable

    4

    {

    5

        use Billable;

    6

    }

    API 密钥

    接下来,需要在配置文件 services.php 中配置如下选项:1

    'braintree' => [

    2

        'model'  => App\User::class,

    3

        'environment' => env('BRAINTREE_ENV'),

    4

        'merchant_id' => env('BRAINTREE_MERCHANT_ID'),

    5

        'public_key' => env('BRAINTREE_PUBLIC_KEY'),

    6

        'private_key' => env('BRAINTREE_PRIVATE_KEY'),

    7

    ],

    然后你需要在服务提供者 AppServiceProvider 的 boot 方法中添加对 Braintree SDK 的调用:1

    \Braintree_Configuration::environment(config('services.braintree.environment'));

    2

    \Braintree_Configuration::merchantId(config('services.braintree.merchant_id'));

    3

    \Braintree_Configuration::publicKey(config('services.braintree.public_key'));

    4

    \Braintree_Configuration::privateKey(config('services.braintree.private_key'));

    货币配置

    Cashier 默认货币是美元(USD),你可以在某个服务提供者的 boot 方法中通过调用 Cashier::useCurrency 方法来更改默认的货币, useCurrency 方法接收两个字符串参数:货币及货币符号:1

    use Laravel\Cashier\Cashier;

    2

    ​

    3

    Cashier::useCurrency('rmb', '¥');

    订阅

    创建订阅

    要创建一个订阅,首先要获取一个账单模型的实例,通常是 App\User 的实例。获取到该模型实例之后,你可以使用 newSubscription 方法来创建该模型的订阅:1

    $user = User::find(1);

    2

    ​

    3

    $user->newSubscription('main', 'premium')->create($token);

    第一个传递给 newSubscription 方法的参数是该订阅的名字,如果应用只有一个订阅,可以将其称作 main 或 primary,第二个参数用于指定用户订阅的 Braintree 计划,该值对应 Braintree 中相应计划的 id。

    create 方法接收信用卡/源令牌,会自动创建这个订阅,同时更新数据库中 对应订阅的客户 ID 和其它相关的账单信息。

    额外的用户信息

    如果你想要指定额外的客户信息,你可以将其作为第二个参数传递给 create 方法:1

    $user->newSubscription('main', 'monthly')->create($stripeToken, [

    2

        'email' => $email,

    3

    ]);

    要了解更多 Braintree 支持的字段,可以查看相应的Braintree文档。

    优惠券

    如果你想要在创建订阅的时候使用优惠券,可以使用 withCoupon 方法:1

    $user->newSubscription('main', 'monthly')

    2

         ->withCoupon('code')

    3

         ->create($token);

    检查订阅状态

    用户订阅你的应用后,你可以使用各种便利的方法来简单检查订阅状态。首先,如果用户有一个有效的订阅,则 subscribed 方法返回 true,即使订阅现在处于试用期:1

    if ($user->subscribed('main')) {

    2

        //

    3

    }

    subscribed 方法还可以用于路由中间件,基于用户订阅状态允许你对路由和控制器的访问进行过滤:1

    public function handle($request, Closure $next){

    2

        if ($request->user() && ! $request->user()->subscribed('main')) {

    3

            // This user is not a paying customer...

    4

            return redirect('billing');

    5

        }

    6

    ​

    7

        return $next($request);

    8

    }

    如果你想要判断一个用户是否还在试用期,可以使用 onTrial 方法,该方法对于还处于试用期的用户显示警告信息很有用:1

    if ($user->->subscription('main')->onTrial()) {

    2

        //

    3

    }

    subscribedToPlan 方法可用于判断用户是否基于 Stripe/Braintree ID 订阅了给定的计划,在本例中,我们会判断用户的 main 订阅是否订阅了 monthly 计划:1

    if ($user->subscribedToPlan('monthly', 'main')) {

    2

        //

    3

    }

    recurring 方法可用于判定用户当前是否已经订阅并且不在试用期:1

    if ($user->subscription('main')->recurring()) {

    2

        //

    3

    }

    已取消的订阅状态

    要判断用户是否曾经是有效的订阅者,但现在取消了订阅,可以使用 cancelled 方法:1

    if ($user->subscription('main')->cancelled()) {

    2

        //

    3

    }

    你还可以判断用户是否曾经取消过订阅,但现在仍然在「宽限期」直到完全失效。例如,如果一个用户在3月5号取消了一个实际有效期到3月10号的订阅,该用户处于「宽限期」直到3月10号。注意 subscribed 方法在此期间仍然返回 true。1

    if ($user->subscription('main')->onGracePeriod()) {

    2

        //

    3

    }

    要判断用户已经取消订阅并且不在「宽限期」内,可以使用 ended 方法:1

    if ($user->subscription('main')->ended()) {

    2

        //

    3

    }

    修改计划

    用户订阅应用后,偶尔想要改变到新的订阅计划,要将用户切换到新的订阅, 传递计划标识到 swap 方法:1

    $user = App\User::find(1);

    2

    $user->subscription('main')->swap('provider-plan-id');

    如果用户在试用,试用期将会被维护。还有,如果订阅存在多个,数量也可以被维护。

    如果你想要切换计划并取消用户所在的所有试用期,你可以使用 skipTrial 方法:1

    $user->subscription('main')

    2

         ->skipTrial()

    3

         ->swap('provider-plan-id');

    订阅税金

    要指定用户支付订阅的税率,实现账单模型的 taxPercentage 方法,并返回一个在0到100之间的数值,不要超过两位小数:1

    public function taxPercentage() {

    2

        return 20;

    3

    }

    这将使你可以在模型基础上使用税率,对跨越不同国家不同税率的用户很有用。

    注: taxPercentage 方法只能用于订阅支付,如果你使用 Cashier 生成一次性账单,需要手动指定税率。

    取消订阅

    要取消订阅,可以调用用户订阅上的 cancel 方法:1

    $user->subscription('main')->cancel();

    当订阅被取消时,Cashier 将会自动设置数据库中的 ends_at 字段。该字段用于了解 subscribed 方法什么时候开始返回 false。例如,如果客户3月1号份取消订阅,但订阅直到3月5号才会结束,那么 subscribed 方法继续返回 true 直到3月5号。

    你可以使用 onGracePeriod 方法判断用户是否已经取消订阅但仍然在“宽限期”:1

    if ($user->subscription('main')->onGracePeriod()) {

    2

        //

    3

    }

    如果你想要立即取消订阅,调用用户订阅上的方法 cancelNow 即可:1

    $user->subscription('main')->cancelNow();

    恢复订阅

    如果用户已经取消订阅但想要恢复该订阅,可以使用 resume 方法,前提是该用户必须在宽限期内:1

    $user->subscription('main')->resume();

    如果该用户取消了一个订阅然后在订阅失效之前恢复了这个订阅,则不会立即支付该账单,取而代之的,他们的订阅只是被重新激活,并回到正常的支付周期。

    订阅试用期

    带信用卡信息

    如果你想要在提供给用户试用期的同时预先收集支付方式信息,可以在创建订阅的时候使用 trialDays 方法:1

    $user = User::find(1);

    2

    ​

    3

    $user->newSubscription('main', 'monthly')

    4

         ->trialDays(10)

    5

         ->create($token);

    该方法会在数据库订阅记录上设置试用期结束日期,以便告知 Braintree 在此之前不要计算用户的账单信息。

    注:如果用户的订阅没有在试用期结束之前取消,则会在试用期结束时立即支付,所以要确保通知用户试用期结束时间。

    可以使用用户实例或订阅实例上的 onTrial 方法判断用户是否处于试用期,下面两个例子作用是等价的:1

    if ($user->onTrial('main')) {

    2

        //

    3

    }

    4

    ​

    5

    if ($user->subscription('main')->onTrial()) {

    6

        //

    7

    }

    不带信用卡信息

    如果你不想在提供试用期的时候收集用户支付方式信息,只需设置用户记录的 trial_ends_at 字段为期望的试用期结束日期即可,这通常在用户注册期间完成:1

    $user = User::create([

    2

        // Populate other user properties...

    3

        'trial_ends_at' => Carbon::now()->addDays(10),

    4

    ]);

    注:确保已添加 trial_ends_at 日期修改器到模型定义。

    Cashier 将这种类型的试用期看作「一般体验」,因为这种使用并没有附加到任何已经在的订阅,如果当前日期没有超过 trial_ends_at 的值, User 实例上的 onTrial 方法将返回 true:1

    if ($user->onTrial()) {

    2

        // User is within their trial period...

    3

    }

    如果你想要知道用户是否在“一般”试用期并且还没有创建实际的订阅还可以使用 onGenericTrial 方法:1

    if ($user->onGenericTrial()) {

    2

        // User is within their "generic" trial period...

    3

    }

    一旦你准备好为用户创建实际的订阅,可以使用 newSubscription 方法:1

    $user = User::find(1);

    2

    ​

    3

    $user->newSubscription('main', 'monthly')->create($token);

    顾客

    创建顾客

    少数情况下,你可能希望创建一个没有开始订阅的 Braintree 顾客,这可以通过 createAsStripeCustomer 方法来实现:1

    $user->createAsStripeCustomer();

    一旦在 Braintree 中创建这样的顾客后,需要在稍晚时候让他开始订阅。

    信用卡

    更新信用卡

    updateCard 方法可用于更新用户的信用卡信息,该方法接收一个 Braintree 令牌并设置新的信用卡作为支付源:1

    $user->updateCard($token);

    处理 Webhooks

    Braintree 可以通过 webhook 通知应用各种事件,要处理 Braintree webhook,需要定义一个指向 Cashier webhook 控制器的路由,这个控制器将会处理所有输入 webhook 请求并将它们分发到合适的控制器方法:1

    Route::post(

    2

        'braintree/webhook',

    3

        '\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook'

    4

    );

    注:注册好控制器后,还要在 Braintree 控制面板中配置 webhook URL。

    默认情况下,这个控制器将会自动对支付失败次数(这个次数可以在 Braintree 设置中定义)过多的订阅进行取消;不过,我们很快会发现,你可以扩展这个控制器来处理任何你想要处理的 webhook 事件。

    Webhooks & CSRF 防护

    由于 webhook 需要绕开 Laravel 的 CSRF 保护,所以需要将其罗列到 VerifyCsrfToken 中间件的排除列表或者将其置于 web 中间件组之外:1

    protected $except = [

    2

        'braintree/*',

    3

    ];

    定义 Webhook 事件处理器

    Cashier 会基于支付失败次数自动取消订阅,但是如果你想要处理额外的 webhook 事件,扩展 Webhook 控制器即可。定义的方法名需要与 Cashier 约定的格式保持一致,特别是方法名需要以 handle 开头并且是想要处理的 webhook 的驼峰格式。例如,如果你想要处理 dispute_opened webhook,则需要添加一个 handleDisputeOpened 方法到控制器:1

    <?php

    2

    ​

    3

    namespace App\Http\Controllers;

    4

    ​

    5

    use Braintree\WebhookNotification;

    6

    use Laravel\Cashier\Http\Controllers\WebhookController as CashierController;

    7

    ​

    8

    class WebhookController extends CashierController

    9

    {

    10

        /**

    11

         * Handle a new dispute.

    12

         *

    13

         * @param  \Braintree\WebhookNotification  $webhook

    14

         * @return \Symfony\Component\HttpFoundation\Responses

    15

         */

    16

        public function handleDisputeOpened(WebhookNotification $webhook)

    17

        {

    18

            // Handle The Webhook...

    19

        }

    20

    }

    失败的订阅

    如果用户的信用卡过期怎么办?不用担心 —— Cashier webhook 控制器可以轻松为你取消该用户的订阅,正如上面所提到的,你所需要做的只是将路由指向该控制器:1

    Route::post(

    2

        'braintree/webhook',

    3

        '\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook'

    4

    );

    就是这样,失败的支付将会被控制器捕获和处理,该控制器将会在 Braintree 判断订阅支付失败次数(通常是3次)达到上限时取消该用户的订阅。不要忘了,你需要在 Braintree 控制面板设置中配置 webhook URI。

    一次性支付

    简单支付

    注:必须传递完整的美元金额到 charge 方法。

    如果你想要使用订阅客户的信用卡一次性结清账单,可以使用账单模型实例上的 charge 方法:1

    $user->charge(1);

    charge 方法接收一个数组作为第二个参数,允许你传递任何你想要传递的底层 Braintree 账单创建参数,创建账单时我们可以参考 Braintree 文档提供的可用选项:1

    $user->charge(1, [

    2

        'custom_option' => $value,

    3

    ]);

    如果支付失败 charge 方法将抛出异常,如果支付成功,该方法会返回完整的 Braintree 响应:1

    try {

    2

        $response = $user->charge(1);

    3

    } catch (Exception $e) {

    4

        //

    5

    }

    带发票的支付

    有时候你需要创建一个一次性支付并且同时生成对应发票以便为用户提供一个PDF单据, invoiceFor 方法可以帮助我们实现这个需求。例如,让我们为用户的「一次性费用」生成一张$5.00的发票:1

    $user->invoiceFor('One Time Fee', 5);

    该单据会通过用户信用卡立即支付, invoiceFor 方法还可以接收一个数组作为第三个参数,该数组包含发票项目的计费选项。在调用 invoiceFor 方法时必须包含 description 选项:1

    $user->invoiceFor('One Time Fee', 5, [

    2

        'description' => 'your invoice description here',

    3

    ]);

    发票

    你可以使用 invoices 方法轻松获取账单模型的发票数组:1

    $invoices = $user->invoices();

    2

    ​

    3

    // Include pending invoices in the results...

    4

    $invoices = $user->invoicesIncludingPending();

    当列出客户发票时,你可以使用发票的辅助函数来显示相关的发票信息。例如,你可能想要在表格中列出每张发票,从而方便用户下载它们:1

    <table>

    2

        @foreach ($invoices as $invoice)

    3

        <tr>

    4

            <td>{{ $invoice->date()->toFormattedDateString() }}</td>

    5

            <td>{{ $invoice->total() }}</td>

    6

            <td><a href="/user/invoice/{{ $invoice->id }}">Download</a></td>

    7

        </tr>

    8

        @endforeach

    9

    </table>

    生成 PDF 发票

    在路由或控制器中,使用 downloadInvoice 方法生成发票的 PDF 下载,该方法将会自动生成相应的 HTTP 响应发送下载到浏览器:1

    use Illuminate\Http\Request;

    2

    ​

    3

    Route::get('user/invoice/{invoice}', function (Request $request, $invoiceId) {

    4

        return $request->user()->downloadInvoice($invoiceId, [

    5

            'vendor'  => 'Your Company',

    6

            'product' => 'Your Product',

    7

        ]);

    8

    });

    Braintree

  • linux 如何添加php gd扩展 (阿里云主机linux添加PHP扩展)全网最强教程

    linux 如何添加php gd扩展 (阿里云主机linux添加PHP扩展)全网最强教程

    linux系统篇

    1.CentOS系统

    关于GD扩展

    gd扩展是一个开源的图像处理库,它通过提供一系列用来处理图片的API,使其可以用来创建图表、图形、缩略图以及其他图像的处理操作。gd扩展支持JPG、PNG、GIF等常见的图片格式,所以在安装php-gd扩展之前,我们需要安装libpng、jpegsrc、freetype这三款软件。下面安装步骤中,具体的路径设置大家根据自己的实际情况进行调整。

    一,首先安装以下内容

    安装 freetype

    wget http://ftp.twaren.net/Unix/NonGNU/freetype/freetype-2.5.5.tar.gz
    tar -xf freetype-2.5.5.tar.gz
    cd freetype-2.5.5
    ./configure --prefix=/usr/local/freetype
    make && make install

    安装jpegsrc

    wget http://www.ijg.org/files/jpegsrc.v9.tar.gz
    tar zxvf jpegsrc.v9.tar.gz
    cd jpeg-9
    ./configure --prefix=/usr/local/jpeg
    make && make install

    安装libpng

    wget http://jaist.dl.sourceforge.net/project/libpng/libpng16/1.6.31/libpng-1.6.31.tar.gz
    tar zxvf libpng-1.6.31.tar.gz 
    cd libpng-1.6.31
    ./configure --prefix=/usr/local/libpng
    make && make install

    二,安装GD扩展

    首先最基本的

    第一:先安装库

    yum -y install libjpeglibjpeg-devel libpng libpng-devel freetype freetype-devel

    第二:进入PHP源码目录下的etc/gd目录

    find / -name gd

    cd /usr/local/php-7.1.16/ext/gd

    执行phpize

    find / -name phpize

    /usr/local/php/bin/phpize

    执行configure:

    注:这里的–with-php-config目录根据自己php的安装路径配置

    find / -name php-config

    ./configure –with-png-dir –with-freetype-dir –with-jpeg-dir –with-gd –with-php-config=/usr/local/php/bin/php-config

    注意了:

    configure: error: jpeglib.h not found

    解决方案:

    执行

    rpm -qa | grep libjpeg

    yum -y install libjpeg-devel

    yum list installed | grep libjpeg

    rpm -ql libjpeg-turbo

    再次执行

    ./configure –with-png-dir –with-freetype-dir –with-jpeg-dir –with-gd –with-php-config=/usr/local/php/bin/php-config

    执行:make && make install

    cd /usr/local/php/lib/php/extensions/no-debug-non-zts-20160303/

    ls

    第三步:修改php.ini

    重启服务 php-rpm

    phpinfo() 查看

    以上是Linux添加PHP扩展的一个实例,如果添加其他扩展遇到其他问题无法解决时请加群讨论智者无惑,仁者无忧,勇者无惧资料来源:https://yq.aliyun.com/articles/277841?spm=5176.10695662.1996646101.searchclickresult.28d7650dugGjcZhttps://www.cnblogs.com/guiyishanren/p/11101839.html

  • 集成PayPal支付(使用BrainTree)

    TIPS: 此文章中的环境仅仅是在SandBox 进行了开发调试!

    说明

    • 为什么选择PayPal
      在国外,多数支付都是采用PayPal或者信用卡进行支付。 注意 对于使用PayPal,其实也有诸多限制,一定要调查清楚了再去分析是否合适自己的项目
    • 为什么使用BrainTree
      在使用PayPal 的时候,我们计划采用集成SDK的方式进行支付。在PayPal的 APP SDK 项目中,已经不再维护 SDK,推荐使用 Braintree Direct 参见: https://github.com/paypal/PayPal-Android-SDK
    • How it works

    准备工作

    配置PayPal

    • 创建Sandbox账号
    1. 登陆后 Dashboard->MyApps&Credentials ;
    2. 选择 Sandbox,然后点击 CreateApp
    3. 填写APP名称,并选择在沙箱中使用的账号
    4. 创建成功后,可以在 MyApps&Credentials 中显示你创建的APP,点击该APP进入项目,可以看到 Sandbox account 、Client ID 、Secret (需要点击show按钮) 

    warn: 此时,尚未有 webhooks 配置

    配置BrainTree

    登陆到沙箱环境 

    • 配置PayPal
    1. 点击 下拉菜单中的 Processing
    2. 找到 PayPal ,点击后面的 “Options” ,去配置PayPal
    3. 分别填入 PayPalEmail 、PayPal Client Id ,PayPal ClientSecret
    • 启用对信用卡的校验
    1. 找到 Processing -> Fraud Tools 中的 CVV,进入
    2. 如图配置
    • 配置WebHooks
    1. 点击 API -> WebHooks -> create new webhook
    2. 填入:Destination URL (HTTPS only),并选择要通知的事件
    3. 校验WebHooks是否正确(需要先开发webhooks功能)

    APP 实现代码

    略

    后台JAVA实现代码

    
    //初始化 gateway
    
    BraintreeGateway gateway = new BraintreeGateway(
    	isProduct ? Environment.PRODUCTION : Environment.SANDBOX,
    	merchant_id,
    	public_key,
    	private_key
    );
    
    //生成token
    String token = gateway.clientToken().generate();
    
    //请求交易
    
    TransactionRequest request = new TransactionRequest()
    	.amount( 这里放金额 )
    	.paymentMethodNonce( 这里放APP提交过来的字符串码 )
    	.orderId( 这里可以放订单号 )
    	.options()
    		.submitForSettlement(true)
    		.paypal()
    		.done()
    	.storeInVaultOnSuccess(true)
    	.done();
    
    Result<Transaction> result = gateway.transaction().sale(request);
    
    

    具体的JAVA代码实现,可以参考官方开发文档: https://developers.braintreepayments.com/guides/paypal/server-side/java

    注意事项

    1. SandBox 环境下 WebHooks无效的问题

    在测试过程中发现,交易成功后,无法收到回调。经过多次google,有提到该问题已经很久(据说修复了,但是一直不能用) 那么可以使用他们提供的 WebhookTestingGateway 进行测试

    WebhookTestingGateway webhookTestingGateway = new WebhookTestingGateway(gateway.getConfiguration() );
    Map<String, String> params =webhookTestingGateway.sampleNotification(WebhookNotification.Kind.SUBSCRIPTION_CHARGED_SUCCESSFULLY, merchant_id);
    
    

    PayPal选择分析

    1、PAYPAL企业账号注册(用于收款、提现的账号)

    部分国家不可以注册

    2、PAYPAL收款的汇率、手续费

    支持银联、Visa、MasterCard、American Express、Discover Card用于支付

       手续费:
       当月累积收款$3000以下,4.4%+$0.3
       当月累积收款$3000-10000,3.9%+$0.3
       当月累积收款$10000-100000,3.7%+$0.3
       当月累积收款$100000,3.4%+$0.3
    
       汇率:
       收款货币使用美元,付款使用人民币,需要付款方把人民币兑换成美元后付款,兑换费率为正常汇率+固定兑换手续费2.5% 
    

    3、PAYPAL提现

       不能提现人民币,只能使用电汇美金形式提现到银行账户(其他PAYPAL不支持的收款币种,都需要已电汇美金形式提现)
       提现必须使用银行账户,需要支持美元
       支持PAYPAL提现的中国银行:工商银行、建设银行、农业银行、中国银行、招商银行、交通银行、中信银行、民生银行、兴业银行、光大银行、华夏银行、浦发银行、邮政银行
    
       提现手续费:
       中国大陆:3-7个工作日,每次$35
       美国:3-4个工作日,每次$35
       中国香港:3-6个工作日,免费(低于1000HKD时,每笔3.5HKD)
    
       提现汇率:
       PAYPAL账户币种与提现币种相同,不需要支付汇率+兑换费,只需支付手续费
       PAYPAL账户币种与提现币种不同,需要支付汇率+2.5%兑换费+手续费
    

    4、PAYPAL支持币种

    收款币种:
      澳元、加元、瑞士法郎、捷克克朗、丹麦克朗、欧元、英镑、港币、福林、以色列新谢克尔、日元、墨西哥比索、挪威克朗、新西兰元、菲律宾比索、波兰兹罗提、俄罗斯卢布、瑞典克朗、新加坡元、泰铢、新台币、美元
      付款币种:100+
    

    5、企业账户身份认证