首页 \ 问答 \ 使用PHP合并PDF文件(Merge PDF files with PHP [closed])

使用PHP合并PDF文件(Merge PDF files with PHP [closed])

我的观点是 - 网站上有10个pdf文件。 用户可以选择一些pdf文件,并选择合并创建包含所选页面的单个pdf文件。 我该怎么用ph​​p这样做?


My concept is - there are 10 pdf files in a website. User can select some pdf files and then select merge to create a single pdf file which contains the selected pages. How can i do this with php?


原文:https://stackoverflow.com/questions/4794435
更新时间:2022-04-28 19:04

最满意答案

我看到很多人拥有一个巨大的源文件。 我是自学成才,所以不知道这是否有益或只是风格。

它通常更好的是具有较小的定义好的文件,而不是一个巨大的源文件。 每个文件都可以有一个C ++类定义或一组相关的函数。 一个粗略的指南不超过几百行C ++代码,但其主观性和难以量化。 你可能经常需要更少或更多。

人们说应该避免使用全局变量,那么我怎样才能在其他文件中提供的函数中声明变量。

您需要将这些变量作为参数传递给这些函数。 例如,如果run_game调用foo,并且foo需要知道当前分数,请将分数作为参数传递,如下所示:

void run_game()
{
     int score = 0;

     ...
     foo(score);
}


void foo(int score)
{ 
    // do some stuff
}

这被称为“按价值传递”,foo正在获得自己的分数副本。 因此,如果foo更新得分,则调用者的副本不会更新。 您可以让foo使用传递引用来更新分数,如下所示:

void foo(int& score) // notice the ampersand
{
    // add 100 pts
    score += 100;
}

现在你可能会问,我有50个变量,我怎么可能把所有50个变成foo? 这就是软件工程的辛勤工作所在。 你有几个选择。 在任何选项中,你都要考虑如何将多个变量组合在一起。 你可能会发现你总是将相同的5个变量传递给函数foo。 也许这是对球员迄今在比赛中取得的成就的一些表示。 将这些聚集在一起的最简单方法是使用一个结构体:

struct PlayerAccomplishments
{
    int playersScore;
    int numGoblinsSlayed;
    int numTrollsSlaved;
};

现在你可以声明这种类型的变量,设置特定的字段并传递它们:

void run_game()
{
     PlayerAccomplishments accomplishments;

     ...
     foo(accomplishments);
}


void foo(PlayerAccomplishments& playerAccomps)
{ 
    // do some stuff
    playerAccomps.numTrollsSlayed++;
    playerAccomps.playerScore += 100;
}

抽象的下一步是将一组变量和常用功能包装到一个类中。 这使我们可以轻松地共享通用功能,并强制执行一个安全的,很好的方式来操作这些对象 - 由该对象的成员函数定义。 例如,如果我们有一个球员类。

class Player
{
private:
    int score;
    int numTrollsSlayed;
public:
    // safely update the player's score after slaying a troll
    void SlayTroll(Troll& aTroll);
};

// in the cpp
Player::SlayTroll(Troll& aTroll)
{
    score += 100;
    numTrollsSlayed += 1;
}

然后上面的代码变成:

void run_game()
{
     Player aPlayer;

     ...
     foo(aPlayer);
}


void foo(Player& aPlayer)
{ 
    Troll someTroll;
    aPlayer.SlayTroll(someTroll); // updates aPlayer's score
}

我希望你能看到有很多方法可以考虑这些问题,并且很难弄清楚如何分离事物。 这个答案几乎没有划伤表面。 我推荐一本好的课程或软件工程书籍 。 这东西很难。 具有数十年经验的真正聪明的人正在与组织和编写软件的最佳方式作斗争。 但是,想想这件事情是很棒的。 很高兴努力找到改进代码的方法,这样您就可以了解今天,明天和六个月后您要做什么。


I see a lot of people having one giant source file. I am self taught so not sure if this has a benefit or is just style.

Its usually better to have smaller well defined files instead of one giant source file. Each file would either have a single C++ class definition or a set of interrelated functions. A rough guideline is no more than a few hundred lines of C++ code, but its subjective and difficult to quantify. You may often need much less or a lot more.

People say globals should be avoided so how can I make variables I declare in functions available in other files.

You need to pass those variables as parameters to those functions. For example if run_game calls foo, and foo needs to know the current score, pass the score in as an argument, like so:

void run_game()
{
     int score = 0;

     ...
     foo(score);
}


void foo(int score)
{ 
    // do some stuff
}

This is known as "pass by value", foo is getting its own copy of score. So if foo updates score, the caller's copy won't get updated. You can let foo update score by using pass by reference as so:

void foo(int& score) // notice the ampersand
{
    // add 100 pts
    score += 100;
}

Now you may ask, well I've got 50 variables, how could I possibly pass all 50 into foo? This is where the hard work of software engineering comes into play. You have a couple of options. In any option, you want to think about how pieces of variables group together. You might find you're always passing the same 5 variables into the function foo. Maybe its some representation of the players accomplishments so far in the game. The simplest way to gorup these together is with a struct:

struct PlayerAccomplishments
{
    int playersScore;
    int numGoblinsSlayed;
    int numTrollsSlaved;
};

Now you can declare variables of this type, set the specific fields, and pass them around:

void run_game()
{
     PlayerAccomplishments accomplishments;

     ...
     foo(accomplishments);
}


void foo(PlayerAccomplishments& playerAccomps)
{ 
    // do some stuff
    playerAccomps.numTrollsSlayed++;
    playerAccomps.playerScore += 100;
}

The next step in abstraction would be wrapping a set of variables and common pieces of functionality into a class. This lets us easily share common functionality and enforce a safe, well way for manipulating these objects--as defined by that object's member functions. So for example if we had a player class.

class Player
{
private:
    int score;
    int numTrollsSlayed;
public:
    // safely update the player's score after slaying a troll
    void SlayTroll(Troll& aTroll);
};

// in the cpp
Player::SlayTroll(Troll& aTroll)
{
    score += 100;
    numTrollsSlayed += 1;
}

Then the code above becomes:

void run_game()
{
     Player aPlayer;

     ...
     foo(aPlayer);
}


void foo(Player& aPlayer)
{ 
    Troll someTroll;
    aPlayer.SlayTroll(someTroll); // updates aPlayer's score
}

I hope you can see that there's a lot of ways to think about these problems, and its not easy to figure out how to seperate things out. This answer barely scratches the surface. I recommend a good course or book in software engineering. This stuff is hard. Really smart people with decades of experience struggle with the best way to organize and write software. But its great to think about this stuff. Its good to work hard to find ways to improve your code so you'll be able to make sense of what you're trying to do today, tomorrow, and six months from now.

相关问答

更多
  • 这是一个明确的标志,您应该将这些单独的块提取到单独的函数中。 MyStruct3 DoSth3(params) { double temporary_var; // Functional step 1.1 // Functional step 1.2 return ... } MyStruct4 DoSth4(params) { double temporary_var; // Functional step 2.1 // Functional st ...
  • 我看到很多人拥有一个巨大的源文件。 我是自学成才,所以不知道这是否有益或只是风格。 它通常更好的是具有较小的定义好的文件,而不是一个巨大的源文件。 每个文件都可以有一个C ++类定义或一组相关的函数。 一个粗略的指南不超过几百行C ++代码,但其主观性和难以量化。 你可能经常需要更少或更多。 人们说应该避免使用全局变量,那么我怎样才能在其他文件中提供的函数中声明变量。 您需要将这些变量作为参数传递给这些函数。 例如,如果run_game调用foo,并且foo需要知道当前分数,请将分数作为参数传递,如下所示: ...
  • 这个重新声明是否使_a等于未知值? 不,这不是“重申声明”。 它是一个名为_a的局部变量的声明。 它是未初始化的。 它与类成员变量_a没有任何关系。 在声明本地_a ,不能再使用_a访问成员变量_a (因为_a指的是局部变量!),但是可以使用this->_a来引用它。 foo()返回后是否超出范围? 是。 局部变量在其声明范围结束时超出范围(这就是“超出范围”的原因)。 Does this re-declaration then make _a equal to an unknown value? No. ...
  • 因为以下for for (initialization ; condition ; increment) { body; } 等同于以下 { initialization; while (condition) { body; increment; } } Because the following for for (initialization ; condition ; increment) { body; } is e ...
  • 这是一个C ++特性的介绍:除非你已经看过一个声明或定义,否则不要假设你知道一个函数签名。 使得在编译器和链接过程中更早地报告不正确的函数使用情况更容易,并且使用C ++名称修改需要确切类型的参数来知道哪些符号需要链接 - 类型确定基于匹配候选对象,可以进行各种标准转换/隐式构造/隐式转换。 解决这个问题的正确方法是创建一个sum.h头文件: #ifndef SUM_H #define SUM_H int sum(int, int); #endif 这应该包含在第一行或sum.cpp (因此,如果sum. ...
  • 以下是使用parallel.foreach循环并行循环多个文件的一个很好的示例: https://msdn.microsoft.com/en-us/library/dd460720(v=vs.110).aspx 该示例适用于某些位图文件。 您只需要替换其lambda表达式中的逻辑,即可将当前文件复制到您希望的位置。 编辑:我根据上面链接中的示例汇总了一些简单的示例代码: List filename = new List(Enumerable.Range(0, 8).Selec ...
  • 不,Python没有头文件也没有相似之处。 Java也没有,尽管你暗示它确实如此。 相反,我们在Python中使用“docstrings”来更容易地找到和使用我们的接口(使用内置的help()函数)。 No, Python does not have header files nor similar. Neither does Java, despite your implication that it does. Instead, we use "docstrings" in Python to make ...
  • 如果CAdWrksSession实际上是一个类而不是一个不透明的指针,我认为在标题中使用的extern "C"会被忽略。 在这个关于extern "C"的行为的堆栈溢出问题中有一些讨论。 确保你的头文件是C的唯一方法是将头文件包含在一个虚拟main.c文件中,并尝试将它与库连接起来。 (让我知道如果你想要更多的澄清这一点) 但是,也许我们可以找到另一种方法来解决您的问题。 我不知道你对这个插件有什么限制。 我建议你创建一个代理库,它是一个私有链接(如果可能,也是静态链接)与遗留代码链接的共享对象。 这是,将 ...
  • 你质疑错过很多细节。 你写跨平台程序吗? 或者它应该只在Windows或* nix上运行? 您对可能的图书馆还有无限的预算吗? 或者您在寻找开源库吗? 所以... 从常识来看,您可以使用跨平台的FFMPEG库。 如果您可以使用Windows平台而不是使用Avisynth ,它提供了非常强大的脚本机制,允许您将多个视频合并为一个,您可以添加自己的过滤器,添加水印或其他类型的效果 You question missed many details. Do you write cross-platform prog ...
  • 在某些情况下,尤其是在同一函数中具有相同名称的两个不同变量的情况下,您无法始终信任调试器以向您提供正确的信息。 如果你要求i的值,调试器可能不知道你指的是哪个。 根据您的描述,听起来编译器为每个不同的i实例分配了两个不同的内存位置。 我经常使用原理当有疑问时,打印出更多 。 如果你使用std::cout << i ,那么你应该看到在打印输出点的范围内的i的实际值。 In some situations, particularly in this case where you have two differe ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)