预处理PHP以从构建的文件中删除功能


Preprocessing PHP to remove functionality from built files

我一直在读关于Phing和Ant的文章,我不确定这些工具中哪一个(如果有的话)对这种情况最有用。

它可以很容易地是调试语句等,但我会给你我们的字面扫描。

我们有一个免费的高级版本的可下载PHP应用程序,而不是只包含一个隐藏在某个地方的变量,然后执行:

if($premium == true) {
   echo 'some additional functionality';
} else {
    echo 'basic functionality';
}

很明显,有人可以获取源代码并更改变量,然后砰的一声——他们偷走了我们的代码。根据我的经验,像Ioncube这样的东西完全不方便,对托管公司的支持也不够好。

我想要点什么。。也许与此类似:

## if premium ##
echo 'some additional functionality';
## else ##
echo 'basic functionality';
## endif ##

然后我会运行两个构建,一个将溢价设置为true,另一个设置为false,这将生成两个简单的文件:

echo 'some additional functionality';

echo 'basic functionality';

基于传递给构建应用程序的相同条件,仅包括整个文件也将非常有帮助。

我找不到这样做的方法,但如果可能的话,我愿意接受任何其他想法。

,帮助会很好

更新

使用C预处理器很棒,看起来它可以完成我需要的一切。然而,我找不到如何做以下三件事。

#1我需要删除生成到输出文件中的注释。下面是一个例子。

# 1 "./index.php"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "./index.php"

我还没有在你链接我的手册页面上找到如何做到这一点的例子。

#2我需要让它递归地遍历每个发现的文件。当我运行当前代码时,我得到一个错误:../target/./folder/test.php: No such file or directory

所以基本上我有我所在的"源"文件夹,其中包含一个名为"文件夹"的子文件夹,它不会重新创建它,也不会重新创建里面的文件(test.php)

#3我相信这个很容易——为了安全起见,我如何让它处理.js文件,可能还有.html?在一个电话里,我的意思是。我认为在.jpg等文件上运行它是个坏主意。。

再次感谢!

很抱歉挖掘这个主题,但我也有同样的需求,CPP方法对我的使用有太多副作用。

因此,我为phing开发了一个基本的预处理器过滤器,它可以做到这一点:

#ifdef premium
  echo 'some additional functionality';
#else
  echo 'basic functionality';
#endif

github上提供了过滤器:https://github.com/tmuguet/PreProcessorFilter

我有了一个想法,在此之前的答案被接受了,但我无论如何都想分享它。所以交易是这样的:

将所有付费功能存储在单独的文件中。使用hook类,您可以检查并在需要的地方添加功能。不要在免费版本的构建中包含付费功能。您将有两个zip文件,但只有一个源文件。

这里有一个非常简单的Hook类,可能会对你有所帮助:

Class Hook {
    var $features_enabled;
    public function __construct() {
        // Construction codes goes here.
        // You can check features files. If there is, require them once
        // if there isnt any, define a variable:
        if (file_exists("./features/feature1.php")) {
            require_once './features/feature1.php';
            // set this true. so we can check the features and run it
            $this->features_enabled = TRUE;
        }
        else {
            // there is no feature avaliable. So there is no need to check functions.
            $this->features_enabled = FALSE;
        }
    }
    /**
     * Check the Feature.
     *
     * @param string The feature name
     * @param array|string|... The arguments that you want to pass.
     */
    public function check($feature_name, $args = NULL) {
        // if features cannot be included on constructor, do not need to check.
        if ($this->features_enabled == FALSE)
            return;
        // if feature is a function: check it then run it
        if (function_exists($feature_name))
            $feature_name($args);
        // if feature is a Class: create it then return it.
        if (class_exists($feature_name))
            return new $feature_name($args);
    }
}

然后,您可以在代码的任何位置签入它们。示例:

$hook = new Hook();
//.... Codes goes here.
// This will check for a function of class. If there is, execute it
$hook->check('feature_badges');

我知道这很简单,需要以许多其他方式发展。但如果你能做到:

  • 您将分离这些功能。通过这种方式,您可以创建不同的包
  • 您将使用类检查功能。即使用户看到了功能名称,也没关系。因为他看不到功能的代码

这是一个相当低的技术,但当然有C预处理器,它可以做你想要的事情;只需输入几个makefile,用findgrep -R调用它,就可以得到一个简单、易于理解的解决方案,其语法您可能知道。

更多详细信息

您可能已经在任何*nix主机上安装了gcc。否则,它将是一个标准包。一些发行版将其单独提供给gcc(如Debian的cpp包)。

该程序有一些简单的指令;wiki页面是一个良好的开端,手册中的详细信息超出了您的需要。基本上,只需使用-E选项在每个文件上调用它来执行宏处理,然后将输出复制到某个构建目录。

你可以用find编写一个单行脚本,沿着find <proj dir> -type f -name '*.php' -exec cpp -E -D <FULL or RESTRICTED> {} -o <build dir>/{} ';的行,并在你的PHP中引用宏FULL和RESTRICTED,比如

#ifdef FULL
    <lines for paying customers>
#endif

UPDATE要使路径正常工作,请尝试以下操作:

#!/bin/bash
cd /.../phing/source/
find . -type f -name '*.php' -exec cpp -E -D FULL {} -o ../target/{} ';

则CCD_ 8应扩展为CCD_ 9。

更新

添加-P以删除线条标记(#1)。添加了一行以复制目录结构(#2)。将文件名匹配更改为在html上的js上运行(#3)。

#!/bin/bash
cd /.../phing/source/
find . -type d -exec mkdir -p ../target/{} ';
find . -type f -regex '.*'.(php|html|js)' -exec cpp -E -P -D FULL {} -o ../target/{} ';

Phing是PHP的Ant。我从来没有使用过Phing,但我认为它是为这样的东西而调整的。

使用Phing创建两个独立的包:一个是高级应用程序,另一个是免费应用程序。

您也可以使用Ant,但是Ant是针对Java进行调优的,而Phing是针对PHP进行调优的。你可能想使用Ant而不是Phing的唯一原因是,Ant可以使用的资源比Phing多得多。但是,如果你是一个PHP商店,学会使用Phing,除非它在简历上看起来很好看。("是的,我是一名资深PHP开发人员。我甚至了解Phing")。

您可以自己构建这样的预处理器-PHP内置了解析PHP文件的支持:http://www.php.net/manual/en/function.token-get-all.php

我用它来构建一个模糊处理程序,必须说它非常容易使用。只需打印您想要的代币,并删除"##如果溢价##"区块内的代币。

更新:我想C预处理器的想法更好。不过,为了完整起见,留下这个答案。:)

免责声明:我完全相信这不是最有效的方法!

--

我分为四个部分:

  • 克隆target中的source目录结构
  • source中的PHP和JS文件解析为target
  • 将所有jpg、gif、css等文件从source复制到target
  • target中的所有PHP和JS文件中删除cpp调用添加的注释

--

find ./ -type d -exec mkdir ../target/{} ';
find ./ -regextype posix-awk -regex "(.*.php|.*.js)" -exec cpp -E -D COMMERCIAL {} -o ../target/{} ';
find ./ -type f -regextype posix-extended -regex "(.*.jpg|.*.gif|.*.png|.*.css|.*.html|.*.txt|.*.xml|.*.ttf)" -exec cp -p --parents "{}" ../target ';
cd ../target
find ./ -regextype posix-awk -regex "(.*.php|.*.js)" -exec sed -i ./{} -e 's/#.*//;/^'s*$/d' ';

--

正如我所说,我确信这不是非常低效,但有一个.sh文件我执行并砰的一声——我有我的构建!