title: PHP Print to Network Printer
body: <h1>What I'm trying to do</h1>
  <p>Print a PDF document on a network printer while passing printing parameters for things such as colour, orientation, duplex, etc.</p>
  <h3>More information</h3>
  <ul>
  <li>We have <strong>multiple network printers</strong>, for which the <strong>IP</strong>s are <strong>static and known</strong> (i.e. 192.168.0.10)</li>
  <li>I found a <strong>document</strong> containing a <strong>list of parameters/options</strong> that can be passed to the printer for changing <strong>print settings</strong> <a href="http://support.ricoh.com/connectivity/etc/pdf/G0816640A.pdf" rel="noreferrer">here</a> (most of which can be found on page 25)</li>
  <li>We are creating a process by which we will be printing a document in black and white EXCEPT the second page. This means that the <strong>first page</strong>, <strong>as well as page 3 and beyond</strong> are <strong>printed</strong> in <strong>black and white</strong>; <strong>page 2</strong> is to be <strong>printed</strong> in <strong>colour</strong>. (This is due to cost of colour printing, plus our other pages don't contain colour, so printing them in colour is EXTREMELY pointless and approx. 8x more expensive - This process will be printing thousands of pages each month, which adds up to a lot of $$$)</li>
  </ul>
  <h1>What I've been <em>somewhat</em> successful with</h1>
  <p>I logged into one of the printers (192.168.0.10 - Ricoh MP C5503 [if you really must know]) and added FTP access</p>
  <p>Printing a document using the command prompt in Windows works!</p>
  <pre><code>&gt; ftp 192.168.0.10
  &gt; User (192.168.0.10:(none)): username
  &gt; Password: password
  &gt; put path\to\file.pdf filetype=PDF
  &gt; bye
  </code></pre>
  <h1>What I've tried to do</h1>
  <p><strong>Attempt 1 using PHP's exec() function</strong></p>
  <p>I've tried MANY ways to make exec work, but to no avail. I have not been able to run multiline commands using PHP's exec function (ideally, running the following). When running the following inside exec(), I am unable to connect to FTP since each line must be executed after the previous line has run. I have found nothing online (multiple Google searches yield no results [except how to echo multiple output lines from cmd - not how to insert multiple cmd lines consecutively])</p>
  <pre><code>&gt; ftp 192.168.0.10
  &gt; User (192.168.0.10:(none)): username
  &gt; Password: password
  &gt; put path\to\test.pdf filetype=PDF
  &gt; bye
  </code></pre>
  <p><strong>Attempt 2 using PHP's exec() function</strong></p>
  <p>I attempted to run the ftp command by passing a text file as some answers on <a href="https://stackoverflow.com/questions/16158138/how-to-ftp-with-a-batch-file">this</a> post suggest. This solution does not work as expected. When running <code>ftp -i -s:test.txt</code> from a command prompt, this works; in PHP, it does not.</p>
  <p>PHP File</p>
  <pre><code>exec(&quot;ftp -i -s:test.txt&quot;);
  </code></pre>
  <p>Text File (<em>test.txt</em>)</p>
  <pre><code>open 192.168.0.10
  username
  password
  put test.pdf filetype=PDF
  bye
  </code></pre>
  <p><strong>Attempt 3 using PHP's FTP functions</strong></p>
  <p>What I can't figure out now, is how to send the file to the printer over ftp and how to set the printer settings</p>
  <pre><code>$ftp = [
      'server'   =&gt; gethostbyaddr('192.168.0.10'),
      'username' =&gt; 'username',
      'password' =&gt; 'password',
  ];
  $conn = ftp_connect($ftp['server']);
  $login = ftp_login($conn, $ftp['username'], $ftp['password']);
  if (is_readable($file)) {
      if (ftp_put($conn, $file, $file, FTP_ASCII)) {
          echo 'Successfully executed command';
      }
      else {
          echo 'Failed execution of command';
      }
  }
  else {
      echo 'File is not readable';
  }
  </code></pre>
  <h1>Ideally...</h1>
  <p>I'm looking for a solution that would work on both Windows and Linux systems as we are also in the process of moving from IIS to NGINX (thank god...). The method that I believe would be the best implementation is using <code>ftp</code> for Windows and <code>rcp</code> or <code>rsh</code> for Linux (since the printer documentation I attached under <em>More information</em> in the <em>What I'm trying to do</em> section mentions these methods for print).</p>
  <p>I'd also like if we did not have to generate txt files or some other file type in order to print these documents. Our users may be processing hundreds of files at once, which I understand we can uniquely name each txt file and then delete after the script has successfully run, although I'd much prefer a clean solution where we can pass in parameters such as printer (IP or name from <code>gethostbyaddr()</code> function), username, password, file to be printed, options (i.e. colour, duplex, filetype, orientation, binding, etc.). We are using MPDF to generate our PDF files, so a method that would place the file without actually creating it on our server where we would then have to delete it would be preferred (i.e. <a href="https://mpdf.github.io/" rel="noreferrer">MPDF</a> string attachment for email) but these are not required.</p>
  <h1>Additionally</h1>
  <p>The solution must work with PHP.</p>
  <p>I will continue to investigate more methods for printing documents on network printers after I post this until a <em>viable</em> solution has been found and update my post accordingly following each attempt.</p>
  <p>Any help regarding this is greatly appreciated.</p>
  <hr />
  <hr />
  <h1>Edits</h1>
  <hr />
  <h2>Unsuccessful methods</h2>
  <h3>Method: PHP Printer functions</h3>
  <p>The <a href="http://php.net/manual/fa/ref.printer.php" rel="noreferrer">printer functions</a> do allow for printing, however they do not allow for control over the print jobs (options such as color/black and white printing, filetype, duplex, etc.). Thus, this options (unless someone has a &quot;hack&quot;, will not work)</p>
  <h3>Method: JavaScript/AJAX</h3>
  <p>Although JavaScript/AJAX would work for printing (and allow print settings), we will be processing potentially hundreds of pages at once and the processing may be pushing print jobs to multiple printers (i.e. in different offices). The idea is to automate our printing for this process and for future processes alike.</p>
  <hr />
  <h2>Untested methods</h2>
  <h3>Methods: Not yet tested</h3>
  <ul>
  <li>Using <a href="https://en.wikipedia.org/wiki/Internet_Printing_Protocol" rel="noreferrer">IPP</a> (as per @Dezza: <a href="https://stackoverflow.com/users/3761174/dezza">Dezza</a>)</li>
  <li>Using <a href="https://www.printnode.com/docs/introduction/" rel="noreferrer">PrintNode</a> (as per @odedta: <a href="https://stackoverflow.com/users/4711865/odedta">odedta</a>)</li>
  </ul>
  <hr />
  <h1>Solution?</h1>
  <p>I ended up creating a C# script to accomplish everything I needed to do. Since my requirements are fairly specific with regards to print settings, <a href="https://docs.microsoft.com/en-us/dotnet/api/system.drawing.printing?view=netframework-4.8" rel="noreferrer">here's a link to Microsoft's System.Drawing.Printing namespace</a>. Using this namespace, I was able to create appropriate methods for my needs. A few StackOverflow questions/answers below that provide more details on usage:</p>
  <ul>
  <li><a href="https://stackoverflow.com/a/32723641">Setting the paper size</a></li>
  <li><a href="https://stackoverflow.com/a/19137591">Set print orientation to landscape</a></li>
  </ul>
  <p>How to run C# in PHP? That's up to you. You can interface with a C# API (having C# run on another web server for example), reference the .NET DLL, use PeachPie, or inject declarations at runtime.</p>
  <ul>
  <li><a href="https://stackoverflow.com/a/27017116">Call a C# .net .dll script using PHP</a></li>
  <li><a href="https://www.peachpie.io/2016/12/php-dotnet-csharp-interoperability.html" rel="noreferrer">Three ways of using C# in PHP with Peachpie Compiler</a></li>
  </ul>
  <hr />
  <p>You may also be able to conjure up something using PowerShell (see <a href="https://docs.microsoft.com/en-us/powershell/module/printmanagement/?view=win10-ps" rel="noreferrer">PrintManagement documentation here</a>). This would allow you to run the script using <code>exec()</code> - see this question regarding the <a href="https://stackoverflow.com/q/5317315">execution of PowerShell from PHP</a>.</p>