分类目录归档:开发技术

使用PHPSTORM和XDEBUG优化PHP程序

Xdebug将程序的中每个函数和方法的运行时间和内存情况,都记录到profiler中,但是需要专门的工具去分析,PhpStorm就提供了这种工具,下面给介绍下使用Phpstorm和Xdebug分析和优化程序。

MAC OS中安装xdebug方法:

brew install php53-xdebug

首先去php.ini配置Xdebug让其记录日志,配置如下

MAC OS的配置文件在/usr/local/etc/php/5.3/conf.d目录中

[xdebug]
zend_extension="/usr/lib/php/extensions/no-debug-non-zts-20090626/xdebug.so"
xdebug.remote_enable=1
xdebug.remote_autostart=1
xdebug.remote_port=9000
;下面就是配置Xdebug分析器的,大家可根据自己的要求,去定制dir和output_name
xdebug.profiler_enable=on
xdebug.trace_output_dir="/tmp"
xdebug.profiler_output_dir="/tmp"
xdebug.profiler_output_name="xdebug"

然后重启apache,然后运行php程序就会在tmp目录下看到xdebug开头的文件。

下一步,用PhpStorm自带工具区分析,选在tools下Analyze Xdebug Profiler Snapshot工具

可以点击Time选项,看看哪个函数消耗的时间长。

amazon mws GetFeedSubmissionResult方法取的正确返回的方法

原sample方法如下:

function invokeGetFeedSubmissionResult(MarketplaceWebService_Interface $service,$request)  {
  try {
          $response = $service->getFeedSubmissionResult($request);
          echo "<br />Var dump here: <pre>";
          print_r($response);
            echo ("<pre>Service Response\n");
            echo ("=============================================================================\n");

            echo("        GetFeedSubmissionResultResponse\n");
            if ($response->isSetGetFeedSubmissionResultResult()) {
              $getFeedSubmissionResultResult = $response->getGetFeedSubmissionResultResult(); 
              echo ("            GetFeedSubmissionResult\n");
              if ($getFeedSubmissionResultResult->isSetContentMd5()) {
                echo ("                ContentMd5\n");
                echo ("                " . $getFeedSubmissionResultResult->getContentMd5() . "\n");
              }
            }
            if ($response->isSetResponseMetadata()) { 
                echo("            ResponseMetadata\n");
                $responseMetadata = $response->getResponseMetadata();
                if ($responseMetadata->isSetRequestId()) 
                {
                    echo("                RequestId\n");
                    echo("                    " . $responseMetadata->getRequestId() . "\n");
                }
            } 

            echo("            ResponseHeaderMetadata: " . $response->getResponseHeaderMetadata() . "\n");
 } catch (MarketplaceWebService_Exception $ex) {
     echo("Caught Exception: " . $ex->getMessage() . "\n");
     echo("Response Status Code: " . $ex->getStatusCode() . "\n");
     echo("Error Code: " . $ex->getErrorCode() . "\n");
     echo("Error Type: " . $ex->getErrorType() . "\n");
     echo("Request ID: " . $ex->getRequestId() . "\n");
     echo("XML: " . $ex->getXML() . "\n");
     echo("ResponseHeaderMetadata: " . $ex->getResponseHeaderMetadata() . "\n");
 }
}

得到的返回如下:

    GetFeedSubmissionResultResponse
        GetFeedSubmissionResult
            ContentMd5
            G5Sw+2ooONEZU1iQoqdEOQ==
        ResponseMetadata
            RequestId
                f9d4be45-6710-42eb-850e-f437224f9938
        ResponseHeaderMetadata: RequestId: f9d4be45-6710-42eb-850e-f437224f9938, ResponseContext: EM/RH7RHQhLSc47Tj2a2Uv2CGKEfvxaKOijjcaKeoh8dGISci3yqo9OHZs7dpLDIszJVz4Jt4z8=,9SYUaktMzcOG6UyuyhXu/kJPl0gpLeenslL2rkugDLhDYftMleRx1XIexbVWNxuYl7cO6901Foiv Kp7hvaLeAQ==, Timestamp: 2013-06-18T07:29:37.393Z

无法查看正确的返回值,原因是因为返回值存在php://memory中,所以正确调用如下:

$filename = __DIR__.'/file.xml';
$handle = fopen($filename, 'w+');
$request = new MarketplaceWebService_Model_GetFeedSubmissionResultRequest();
$request->setMerchant(MERCHANT_ID);
$request->setFeedSubmissionId(ID_TO_CHANGE);
$request->setFeedSubmissionResult($handle);


try {
    $response = $service->getFeedSubmissionResult($request);
    fclose($handle);

    echo ("Service Response\n");
    echo ("=============================================================================\n");

    echo("        GetFeedSubmissionResultResponse\n");
    if ($response->isSetGetFeedSubmissionResultResult()) {
        $getFeedSubmissionResultResult = $response->getGetFeedSubmissionResultResult();
        echo ("            GetFeedSubmissionResult");

        if ($getFeedSubmissionResultResult->isSetContentMd5()) {
            echo ("                ContentMd5");
            echo ("                " . $getFeedSubmissionResultResult->getContentMd5() . "\n");
        }
    }
    if ($response->isSetResponseMetadata()) {
        echo("            ResponseMetadata\n");
        $responseMetadata = $response->getResponseMetadata();
        if ($responseMetadata->isSetRequestId())
        {
            echo("                RequestId\n");
            echo("                    " . $responseMetadata->getRequestId() . "\n");
        }
    }

    echo("            ResponseHeaderMetadata: " . $response->getResponseHeaderMetadata() . "\n");
} catch (MarketplaceWebService_Exception $ex) {
    echo("Caught Exception: " . $ex->getMessage() . "\n");
    echo("Response Status Code: " . $ex->getStatusCode() . "\n");
    echo("Error Code: " . $ex->getErrorCode() . "\n");
    echo("Error Type: " . $ex->getErrorType() . "\n");
    echo("Request ID: " . $ex->getRequestId() . "\n");
    echo("XML: " . $ex->getXML() . "\n");
    echo("ResponseHeaderMetadata: " . $ex->getResponseHeaderMetadata() . "\n");
}

可以到file.xml文件中查看到实际的返回如下:

<?xml version="1.0" encoding="UTF-8"?>
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
	<Header>
		<DocumentVersion>1.02</DocumentVersion>
		<MerchantIdentifier>M_INKMARKET_01770947</MerchantIdentifier>
	</Header>
	<MessageType>ProcessingReport</MessageType>
	<Message>
		<MessageID>1</MessageID>
		<ProcessingReport>
			<DocumentTransactionID>10771673618</DocumentTransactionID>
			<StatusCode>Complete</StatusCode>
			<ProcessingSummary>
				<MessagesProcessed>1</MessagesProcessed>
				<MessagesSuccessful>0</MessagesSuccessful>
				<MessagesWithError>1</MessagesWithError>
				<MessagesWithWarning>1</MessagesWithWarning>
			</ProcessingSummary>
			<Result>
				<MessageID>0</MessageID>
				<ResultCode>Warning</ResultCode>
				<ResultMessageCode>90061</ResultMessageCode>
				<ResultDescription>The Message/Product/SKU field heading is invalid, so values in this field were ignored. To correct this error, download the template again and use the new copy, or fix the field heading in your existing file.</ResultDescription>
			</Result>
			<Result>
				<MessageID>1</MessageID>
				<ResultCode>Error</ResultCode>
				<ResultMessageCode>5000</ResultMessageCode>
				<ResultDescription>XML Parsing Error at Line 13, Column 38: cvc-complex-type.2.4.a: Invalid content was found starting with element &apos;MSRP&apos;. One of &apos;{Title}&apos; is expected.</ResultDescription>
			</Result>
		</ProcessingReport>
	</Message>
</AmazonEnvelope>

mac osx中python不能使用easy_install的解决办法

1. 检查easy_install的安装位置,正常情况下在/usr/bin或者/usr/local/bin中,要把找到的先删除,因为可能是版本不一致导致的不能使用。

sudo rm /usr/bin/easy_install*

sudo rm /usr/local/bin/easy_install*

2. 下载并且运行distribute

curl -O http://python-distribute.org/distribute_setup.py

sudo python distribute_setup.py

sudo rm distribute_setup.py

3. 使用easy_install测试安装pip

sudo easy_install pip

mac osx安装apache hive

1. 通过homebrew安装hive

brew install hive

2. 添加hadoop和hive的环境变量

sudo vim ~/.bash_profile

export HADOOP_HOME=/usr/local/Cellar/hadoop/hadoop.version.no
export HIVE_HOME=/usr/local/Cellar/hive/hive.version.no/libexec

source ~/.bash_profile

3. 下载mysql connector

curl -L 'http://www.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.22.tar.gz/from/http://mysql.he.net/' | tar xz

sudo cp mysql-connector-java-5.1.15/mysql-connector-java-5.1.22-bin.jar /usr/local/Cellar/hive/hive.version.no/libexec/lib/

4. 创建mysql metastore

mysql> CREATE DATABASE metastore;
mysql> USE metastore;
mysql> CREATE USER 'hiveuser'@'localhost' IDENTIFIED BY 'password';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,ALTER,CREATE ON metastore.* TO 'hiveuser'@'localhost';

5. 配置hive的配置文件

cd /usr/local/Cellar/hive/hive.version.no/libexec/conf
cp hive-default.xml.template hive-site.xml

#添加或者编辑如下内容
<property>
  <name>javax.jdo.option.ConnectionURL</name>
  <value>jdbc:mysql://localhost/metastore</value>
</property>
<property>
  <name>javax.jdo.option.ConnectionDriverName</name>
  <value>com.mysql.jdbc.Driver</value>
</property>
<property>
  <name>javax.jdo.option.ConnectionUserName</name>
  <value>hiveuser</value>
</property>
<property>
  <name>javax.jdo.option.ConnectionPassword</name>
  <value>password</value>
</property>
<property>
  <name>datanucleus.fixedDatastore</name>
  <value>false</value>
</property>

6. 测试hive是否工作

$ hive;
hive > show tables;
hive> create table temp_table temp_col string;

7. Revoke few permissions on the mysql metastore

$ mysql
mysql> REVOKE ALTER,CREATE ON metastore.* FROM 'hiveuser'@'localhost';

9. Further troubleshooting : 
(a) If you get a bin log error saying statement format is not support. Login to your mysql console as root

$ mysql -uroot
mysql > SET GLOBAL binlog_format = 'ROW';

(b) You could also try reading the logs as follows. Logs can be emitted to the bash prompt while running hive by setting hive.root.logger to INFO,console.

$ hive -hiveconf hive.root.logger=INFO,console

(c)You could also read the raw hive logs which is usually located at /tmp/user_name/hive.log

(d)If you still have any errors, feel free to comment.

 

升级MAC OX上的Python到3.4版本

1. 下载最新的python3.4
下载Mac OS X 64-bit/32-bit installer
https://www.python.org/downloads/release/python-340/

2.安装DMG文件
安装下载的dmg文件

3. 配置

#!/bin/bash
#python版号需要修改两个地方
#1. new_version

#sudo -i #得到超级权限
new_version="3.4"

PYPATH=/System/Library/Frameworks/Python.framework/Versions/"$new_version"
#第1步移动新版python到mac默认目录下
echo "move.."
mv /Library/Frameworks/Python.framework/Versions/"$new_version" /System/Library/Frameworks/Python.framework/Versions/
#第2步改变用户目录的用户组
echo "chown.."
chown -R root:wheel ${PYPATH}
#第3步 删除原来2.7的链接
echo "del.."
rm /System/Library/Frameworks/Python.framework/Versions/Current
#第4步重新链接到最新版本的python
echo "ln.."
ln -s ${PYPATH} /System/Library/Frameworks/Python.framework/Versions/Current
#第5步删除旧的命令符号链接
echo "rm.."
rm /usr/bin/{pydoc,python,pythonw,python-config}
echo "ln bin.."
#第6步重新建立新的命令符号链接
ln -s ${PYPATH}/bin/pydoc"$new_version" /usr/bin/pydoc
ln -s ${PYPATH}/bin/python"$new_version" /usr/bin/python
ln -s ${PYPATH}/bin/pythonw"$new_version" /usr/bin/pythonw
ln -s ${PYPATH}/bin/python"$new_version"m-config /usr/bin/python-config


python_param_list=`cd /usr/local/bin && ls -al |grep "Python"|awk 'ORS=" " {print $9}'`
#第7步修复其他链接
for i in $python_param_list;do
  echo "info: $i"
  rm -f /usr/local/bin/${i}
  ln -sv /System/Library/Frameworks/Python.framework/Versions/"$new_version"/bin/${i} /usr/local/bin/${i}
done

#第8步.环境变量要修改为最新的版本号
echo 'export PATH=/System/Library/Frameworks/Python.framework/Versions/3.4/bin:${PATH}' >> ~/.bashrc

exit #退出超级权限

SSMTP出现send-mail: Cannot open smtp.gmail.com:587问题解决

如果你通过用SSMTP通过GMAIL的SMTP来发送邮件,遇到如下错误:

send-mail: Cannot open smtp.gmail.com:587

首先查看/var/log/maillog日志,看具体报的是什么错误,如果是如下:

sSMTP: SSL not working: certificate verify failed (20)
sSMTP: Cannot open smtp.gmail.com:587

在/etc/ssmtp/ssmtp.conf文件中添加如下:

TLS_CA_File=/etc/pki/tls/certs/ca-bundle.crt

即可解决问题

Magento从1.7版本升级到1.8版本的方法。

1. 设置站点为维护模式:

cd /你的magento根目录
touch maintenance.flag

2. 备份当前的数据库:

mysqldump -uroot -p 数据库名 > 数据库名.sql

3. 备份当前网站的目录:

cp -R /你的magento根目录 备份目录名

4. 更新:

cd /你的magento根目录
chmod -R 777 ./*
rm -rf var/cache/* var/session/*
chmod 550 ./mage
./mage mage-setup .
./mage config-set preferred_state stable
./mage list-installed

如果最后的命令不会列出预期Magento的模块,如:

Installed package for channel 'community' :
Lib_Js_Ext           1.7.0.0 stable
Lib_LinLibertineFont 2.8.14.1 stable
Lib_Js_TinyMCE       3.4.7.0 stable
Lib_Js_Calendar      1.51.1.1 stable
Lib_Phpseclib        1.5.0.0 stable
Lib_ZF               1.11.1.0 stable
Lib_Js_Prototype     1.7.0.0.4 stable
Lib_ZF_Locale        1.11.1.0 stable
Mage_All_Latest      1.7.0.2 stable
Interface_Adminhtml_Default 1.7.0.2 stable
Interface_Frontend_Default 1.7.0.2 stable
Interface_Install_Default 1.7.0.2 stable
Mage_Downloader      1.7.0.2 stable
Mage_Centinel        1.7.0.2 stable
Interface_Frontend_Base_Default 1.7.0.20 stable
Phoenix_Moneybookers 1.3.2 stable
Mage_Compiler        1.7.0.2 stable
Magento_Mobile       1.7.0.2.23.1 stable
Mage_Core_Adminhtml  1.7.0.2 stable
Mage_Core_Modules    1.7.0.2 stable
Lib_Varien           1.7.0.2 stable
Lib_Google_Checkout  1.7.0.2 stable
Lib_Js_Mage          1.7.0.2 stable
Mage_Locale_en_US    1.7.0.2 stable
Lib_Mage             1.7.0.2 stable

则使用如下命令:

./mage install http://connect20.magentocommerce.com/community Mage_All_Latest --force

如果您的Magento模块列举成功然后使用下面的命令:

./mage list-upgrades
./mage upgrade-all

如上命令执行完成,会看到哪些升级成功,哪些没有升级;升级后要恢复目录的权限:

php shell/indexer.php reindexall
chmod -R 644 ./*
find . -type d -exec chmod 755 {} \;
chmod 550 ./mage

升级成功后恢复网站在线:

cd /your_magento_folder
rm -f maintenance.flag

git单独checkout版本库中的指定目录

初始化空仓储:

git init && cd

git remote add –f

打开sparse-checkout特性:

git config core.sparsecheckout true

配置.git/info/sparse-checkout,列出你想要checkout的目录:

echo some/dir/ >> .git/info/sparse-checkout

echo another/sub/tree >> .git/info/sparse-checkout

从远端获取代码:

git pull <定义的版本库名> maste(可获取其他分支的代码)

 

更多信息可见:http://jasonkarns.com/blog/subdirectory-checkouts-with-git-sparse-checkout/

MAC下通过FileMerge来合并两个文件夹

我们都知道在windows下如果把某个地方的文件夹A, 拷贝到另一个地方, 如果那个地方也有A, 那么就会自动合并.

不过mac下没有这种功能, 文件一多就有点麻烦…

mac下的开发工具里提供了一个FileMerge app, 可以用来进行合并操作. 比如此工具功能有点过份强大, 看起来有点搞不清楚状态. 如果只使用merge directory这个功能, 那么操作就简单了…

在Developer里打开FileMerge,

Left… 选择补丁文件的目录

Right… 选择需要打补丁的文件的目录

然后Compare, 出来:

在第一列选中所有, 然后右侧 Merge -> 选 Combine Files.  会弹出一个窗口会问你是否新建一个目录(就是把两则merge到这个目录), 显然我们不想那么做, 所以选择另外一个. 就是Right目录, 选Open,  返回就行了.

此时, 左列状态会打上勾, 表示处理过的目录/文件.

你可以到Right目录,发现补丁已经被打进去了…

PHP截取英文保证单词完整性

/**
     * 完整词的截取
     *
     * @param $str
     * @param $start
     * @param $length
     *
     * @return string
     */
    public static function usubstr($str, $start, $length = null)
    {

        // 先正常截取一遍.
        $res = substr($str, $start, $length);
        $strlen = strlen($str);

        /* 接着判断头尾各6字节是否完整(不残缺) */
        // 如果参数start是正数
        if ($start >= 0) {
            // 往前再截取大约6字节
            $next_start = $start + $length; // 初始位置
            $next_len = $next_start + 6 <= $strlen ? 6 : $strlen - $next_start;
            $next_segm = substr($str, $next_start, $next_len);
            // 如果第1字节就不是 完整字符的首字节, 再往后截取大约6字节
            $prev_start = $start - 6 > 0 ? $start - 6 : 0;
            $prev_segm = substr($str, $prev_start, $start - $prev_start);
        } // start是负数
        else {
            // 往前再截取大约6字节
            $next_start = $strlen + $start + $length; // 初始位置
            $next_len = $next_start + 6 <= $strlen ? 6 : $strlen - $next_start;
            $next_segm = substr($str, $next_start, $next_len);

            // 如果第1字节就不是 完整字符的首字节, 再往后截取大约6字节.
            $start = $strlen + $start;
            $prev_start = $start - 6 > 0 ? $start - 6 : 0;
            $prev_segm = substr($str, $prev_start, $start - $prev_start);
        }
        // 判断前6字节是否符合utf8规则
        if (preg_match('@^([x80-xBF]{0,5})[xC0-xFD]?@', $next_segm, $bytes)) {
            if (!empty($bytes[1])) {
                $bytes = $bytes[1];
                $res .= $bytes;
            }
        }
        // 判断后6字节是否符合utf8规则
        $ord0 = ord($res[0]);
        if (128 <= $ord0 && 191 >= $ord0) {
            // 往后截取 , 并加在res的前面.
            if (preg_match('@[xC0-xFD][x80-xBF]{0,5}$@', $prev_segm, $bytes)) {
                if (!empty($bytes[0])) {
                    $bytes = $bytes[0];
                    $res = $bytes . $res;
                }
            }
        }
        if (strlen($res) < $strlen) {
            $res = $res . '...';
        }
        return $res;
    }