dompdf:base64图像无法在Google App Engine上运行

时间:2018-04-19 04:47:55

标签: php google-app-engine dompdf

我希望有人可以告诉我这是我的代码有问题还是dompdf + GAE的错误。

以下代码适用于使用Google App Engine SDK的本地开发服务器,但不适用于实时GAE项目。

其他基于文件的图像有效,但我无法获得任何base64图像(包括这个简单的示例图像)在线工作。

输出给出一个带有X的框,表示"图像未找到或输入未知"。

有什么想法吗?

 class ServicePaymentsController < ApplicationController
   before_action :authenticate_user!
   def index
     @service_payments = current_user.company.service_payments.all( :limit => 10, :order => "id DESC" )
   end

   def subscribe_month
     @service_payment = ServicePayment.new
     @service_payment.amount = ClienteEspecial::MONTHLY_PRICE
     @service_payment.description = t("helpers.links.subscribe_month") 
     @service_payment.period = 'month'  
     @service_payment.method = 'Mercado Pago'
     @service_payment.state = params[:state]  
     @service_payment.payment_id = params[:payment_id]           
     subscribe(@service_payment)
   end  

  def subscribe_year
    @service_payment = ServicePayment.new
    @service_payment.amount = ClienteEspecial::YEARLY_PRICE
    @service_payment.description = t("helpers.links.subscribe_year") 
    @service_payment.period = 'year'  
    @service_payment.method = 'Mercado Pago'  
    @service_payment.state = params[:state]   
    @service_payment.payment_id = params[:payment_id]      
    subscribe(@service_payment)
  end

  def subscribe(service_payment)
    service_payment.domain = current_user.domain
    if service_payment.save
      if service_payment.state =='approved' 
        execute(service_payment)
        redirect_to company_path(:id => current_user.company.id), :notice => t('helpers.labels.service_payments')+" "+t('helpers.labels.approved')
      else
        redirect_to company_path(:id => current_user.company.id), :notice => t('helpers.labels.service_payments')+" "+t('helpers.labels.cancelled')+" ("+service_payment.state.to_s+")"
      end
    else
      render company_path(:id => current_user.company.id), :alert  => service_payment.errors.to_a.join(", ")
    end
  end

  def execute(service_payment)
   if service_payment.period == "month"
     @company = current_user.company
     @company.plan = "PAGO"
     @company.initial_cycle = Time.new
     @company.final_cycle = Time.now.months_since(1)
     @company.counter = 0
     @company.limit = 1000000
     @company.save
   elsif service_payment.period == "year"
     @company = current_user.company
     @company.plan = "PAGO"
     @company.initial_cycle = Time.new
     @company.final_cycle = Time.now.years_since(1)
     @company.counter = 0
     @company.limit = 1000000
     @company.save
   end           
 end

 private
    # Use callbacks to share common setup or constraints between actions.
    def set_service_payment
      @service_payment = ServicePayments.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def service_payment_params
      params.require(:service_payment).permit(:amount, :description, :payment_id, :state, :period, :method, :domain)
    end

end

1 个答案:

答案 0 :(得分:0)

我相信我有答案:

在dompdf的Cache.php中,base64图像首先写入文件,GAE上存在两个问题。

  1. file_put_contents()只能与GAE中的storage bucket一起使用。
  2. tempnam()似乎在GAE中效果不佳。
  3. 要解决问题1,您需要设置一个临时目录,即存储桶。在GAE环境中,使用问题的示例代码,如下所示:

    $options->set('tempDir', 'gs://myappname.appspot.com/mytempfolder/');
    

    关于问题2,tempnam()会导致GAE出现问题,因为:

      

    如果目录不存在或不可写,则tempnam()可以   在系统的临时目录中生成一个文件......

    根据http://php.net/manual/en/function.tempnam.php。我的假设是tempname无法正确处理存储桶存储桶。我的解决方案是在dompdf的\src\Image\Cache.php文件中找到这一行:

    $resolved_url = tempnam($tmp_dir, "ca_dompdf_img_");
    

    并将其替换为:

    $resolved_url = $tmp_dir . uniqid("ca_dompdf_img_") . ".tmp";
    

    注意:要使其正常工作,您的tempDir必须按照上面的示例结束/。它也必须存在。

    所以我们基本上告诉dompdf使用一个与GAE一起使用的临时目录,并绕过一个在GAE中不能正常工作的函数。