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

时间:2011-05-27 14:07:46

标签: php ant build phing

我一直在阅读有关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 ##

然后我会运行两个构建,一个将premium设置为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

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

#3 我确信这个很容易 - 我怎样才能让它处理.js文件,也可能是.html也是为了安全起见?在一个电话中,我的意思是。我假设在.jpg等文件上运行它是一个坏主意..

再次感谢!

6 个答案:

答案 0 :(得分:4)

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

所以我为phing开发了一个基本的预处理器过滤器,可以解决这个问题:

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

过滤器可在github上找到:https://github.com/tmuguet/PreProcessorFilter

答案 1 :(得分:1)

我已经提出了一个想法,之前的答案已被接受,但无论如何我想分享它。所以这是交易:

将所有付费功能存储在单独的文件中。使用钩子类,您可以检查并添加所需的功能。不要在免费版本的构建中包含付费功能。你将有2个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');

我知道这很简单,需要以许多其他方式进行开发。但如果你能管理它:

  • 您将分开这些功能。这样,您就可以创建不同的包。
  • 您将通过课程检查功能。即使用户看到功能名称,也没关系。因为他看不到该功能的代码。

答案 2 :(得分:0)

这是非常低技术的,但当然有C预处理器可以完全按照您的要求进行操作;只需用几个makefile就可以用findgrep -R来调用它,你会得到一个简单易懂的解决方案,你可能知道它的语法。

更多细节

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

该程序有一些简单的指示; wiki page是一个好的开始,而manual的详细程度超出了您的需求。基本上,只需要使用-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

更新要使路径正常运行,请尝试以下方法:

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

然后../target/{}应扩展为../target/./index.php

<强>更新

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

#!/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/{} \;

答案 3 :(得分:0)

好吧,Phing是PHP的Ant。我从未使用过Phing,但我认为它已经针对这样的东西进行了调整。

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

您也可以使用Ant,但是针对Java调整了Ant,而Phing针对PHP进行了调整。您可能希望使用Ant over Phing的唯一原因是Ant可用的资源比Phing多得多。但是,如果你是一个PHP商店,学会使用Phing,除了它在简历上看起来不错。 (“是的,我是高级PHP开发人员。我甚至知道Phing”)。

答案 4 :(得分:0)

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

我用它来构建一个混淆器,必须说它很容易使用。只需打印您想要的令牌,然后删除“## if premium ##”块内的令牌。

更新:我猜C预处理器的想法更好。但是,为了完整性而留下这个答案。 :)

答案 5 :(得分:0)

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

-

我分为四部分:

  • 克隆source
  • 中的target目录结构
  • 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文件 - 我有我的版本!