在 Laravel 5.3 中导入 Quickbook 库时出错

Error while importing Quickbook library in Laravel 5.3

我正在将 quickbooks 与我的 laravel 应用程序集成。集成后我得到这个错误,

PHP Warning: require_once(../QuickBooks.php): failed to open stream: No such file or directory in /home/vipin/projects/development/Quickbook/config/app.php on line 2 PHP Fatal error: require_once(): Failed opening required '../QuickBooks.php' (include_path='.:/usr/share/php:/home/ubuntu/projects/development/Quickbook/vendor/consolibyte/quickbooks') in /home/ubuntu/projects/development/Quickbook/config/app.php on line 2

这是我的控制器Quickbook.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
// require_once '../QuickBooks.php';

use App\Http\Requests;

class QuickBooksController extends Controller
{
private $IntuitAnywhere;
private $context;
private $realm;

public function __construct(){
  if (!\QuickBooks_Utilities::initialized(env('QBO_DSN'))) {
      // Initialize creates the neccessary database schema for queueing up requests and logging
      \QuickBooks_Utilities::initialize(env('QBO_DSN'));
  }
  $this->IntuitAnywhere = new \QuickBooks_IPP_IntuitAnywhere(env('QBO_DSN'), env('QBO_ENCRYPTION_KEY'), env('QBO_OAUTH_CONSUMER_KEY'), env('QBO_CONSUMER_SECRET'), env('QBO_OAUTH_URL'), env('QBO_SUCCESS_URL'));
}

public function  qboConnect(){
  if ($this->IntuitAnywhere->check(env('QBO_USERNAME'), env('QBO_TENANT')) && $this->IntuitAnywhere->test(env('QBO_USERNAME'), env('QBO_TENANT'))) {
      // Set up the IPP instance
      $IPP = new \QuickBooks_IPP(env('QBO_DSN'));
      // Get our OAuth credentials from the database
      $creds = $this->IntuitAnywhere->load(env('QBO_USERNAME'), env('QBO_TENANT'));
      // Tell the framework to load some data from the OAuth store
      $IPP->authMode(
          \QuickBooks_IPP::AUTHMODE_OAUTH,
          env('QBO_USERNAME'),
          $creds);

      if (env('QBO_SANDBOX')) {
          // Turn on sandbox mode/URLs
          $IPP->sandbox(true);
      }
      // This is our current realm
      $this->realm = $creds['qb_realm'];
      // Load the OAuth information from the database
      $this->context = $IPP->context();

      return true;
  } else {
      return false;
  }
}

public function qboOauth(){
  if ($this->IntuitAnywhere->handle(env('QBO_USERNAME'), env('QBO_TENANT')))
  {
      ; // The user has been connected, and will be redirected to QBO_SUCCESS_URL automatically.
  }
  else
  {
      // If this happens, something went wrong with the OAuth handshake
      die('Oh no, something bad happened: ' . $this->IntuitAnywhere->errorNumber() . ': ' . $this->IntuitAnywhere->errorMessage());
  }
}

public function qboSuccess(){
  return view('qbo_success');
}

public function qboDisconnect(){
  $this->IntuitAnywhere->disconnect(env('QBO_USERNAME'), env('QBO_TENANT'),true);
  return redirect()->intended("/yourpath");// afer disconnect redirect where you want

}

public function createCustomer(){

  $CustomerService = new \QuickBooks_IPP_Service_Customer();

  $Customer = new \QuickBooks_IPP_Object_Customer();
  $Customer->setTitle('Ms');
$Customer->setGivenName('Shannon');
$Customer->setMiddleName('B');
$Customer->setFamilyName('Palmer');
$Customer->setDisplayName('Shannon B Palmer ' . mt_rand(0, 1000));
  // Terms (e.g. Net 30, etc.)
  $Customer->setSalesTermRef(4);

  // Phone #
  $PrimaryPhone = new \QuickBooks_IPP_Object_PrimaryPhone();
  $PrimaryPhone->setFreeFormNumber('860-532-0089');
$Customer->setPrimaryPhone($PrimaryPhone);

  // Mobile #
  $Mobile = new \QuickBooks_IPP_Object_Mobile();
  $Mobile->setFreeFormNumber('860-532-0089');
$Customer->setMobile($Mobile);

  // Fax #
  $Fax = new \QuickBooks_IPP_Object_Fax();
  $Fax->setFreeFormNumber('860-532-0089');
$Customer->setFax($Fax);

  // Bill address
  $BillAddr = new \QuickBooks_IPP_Object_BillAddr();
  $BillAddr->setLine1('72 E Blue Grass Road');
$BillAddr->setLine2('Suite D');
$BillAddr->setCity('Mt Pleasant');
$BillAddr->setCountrySubDivisionCode('MI');
$BillAddr->setPostalCode('48858');
$Customer->setBillAddr($BillAddr);

  // Email
  $PrimaryEmailAddr = new \QuickBooks_IPP_Object_PrimaryEmailAddr();
  $PrimaryEmailAddr->setAddress('support@consolibyte.com');
  $Customer->setPrimaryEmailAddr($PrimaryEmailAddr);

  if ($resp = $CustomerService->add($this->context, $this->realm, $Customer))
  {
      //print('Our new customer ID is: [' . $resp . '] (name "' . $Customer->getDisplayName() . '")');
      //return $resp;
      //echo $resp;exit;
      //$resp = str_replace('{','',$resp);
      //$resp = str_replace('}','',$resp);
      //$resp = abs($resp);
      return $this->getId($resp);
  }
  else
  {
      //echo 'Not Added qbo';
      print($CustomerService->lastError($this->context));
  }
}

public function addItem(){
  $ItemService = new \QuickBooks_IPP_Service_Item();

  $Item = new \QuickBooks_IPP_Object_Item();

  $Item->setName('My Item');
$Item->setType('Inventory');
$Item->setIncomeAccountRef('53');

  if ($resp = $ItemService->add($this->context, $this->realm, $Item))
  {
      return $this->getId($resp);
  }
  else
  {
      print($ItemService->lastError($this->context));
  }
}

public function addInvoice($invoiceArray,$itemArray,$customerRef){

  $InvoiceService = new \QuickBooks_IPP_Service_Invoice();

  $Invoice = new \QuickBooks_IPP_Object_Invoice();

  $Invoice = new QuickBooks_IPP_Object_Invoice();

$Invoice->setDocNumber('WEB' . mt_rand(0, 10000));
$Invoice->setTxnDate('2013-10-11');

$Line = new QuickBooks_IPP_Object_Line();
$Line->setDetailType('SalesItemLineDetail');
$Line->setAmount(12.95 * 2);
$Line->setDescription('Test description goes here.');

$SalesItemLineDetail = new QuickBooks_IPP_Object_SalesItemLineDetail();
$SalesItemLineDetail->setItemRef('8');
$SalesItemLineDetail->setUnitPrice(12.95);
$SalesItemLineDetail->setQty(2);

$Line->addSalesItemLineDetail($SalesItemLineDetail);

$Invoice->addLine($Line);

$Invoice->setCustomerRef('67');


  if ($resp = $InvoiceService->add($this->context, $this->realm, $Invoice))
  {
      return $this->getId($resp);
  }
  else
  {
      print($InvoiceService->lastError());
  }
}

public function getId($resp){
  $resp = str_replace('{','',$resp);
  $resp = str_replace('}','',$resp);
  $resp = abs($resp);
  return $resp;
}

}

Config/app.php

<?php
require_once '../QuickBooks.php';

return [


    'qbo_token' => env('QUICKBOOK_TOKEN'),
    'qbo_consumer_key' => env('QBO_OAUTH_CONSUMER_KEY'),
    'qbo_consumer_secret' => env('QBO_CONSUMER_SECRET'),
    'qbo_sandbox' => env('QBO_SANDBOX'),
    'qbo_encryption_key' => env('QBO_ENCRYPTION_KEY'),
    'qbo_username' => env('QBO_USERNAME'),
    'qbo_tenant' => env('QBO_TENANT'),
    'qbo_auth_url' => 'http://app.localhost:8000/qbo/oauth',
    'qbo_success_url' => 'http://app.localhost:8000/qbo/success',
    'qbo_mysql_connection' => 'mysqli://'. env('DB_USERNAME') .':'. env('DB_PASSWORD') .'@'. env('DB_HOST') .'/'. env('DB_DATABASE'),

使用 require 而不是自动加载器在现代框架中是一种不好的做法(通常在现代 PHP 中)。我强烈建议使用包管理器(例如 composer)将模块正确添加到项目中。

例如,要使用 composer 将 quickbooks 库添加到项目中,您只需要 运行 一个命令:

composer require consolibyte/quickbooks

使用给定的代码和方法,这里有几个方面需要改进。

  1. 作为,您不应该直接要求任何quickbooks 库文件。如果您通过 Composer 加载了它,那么它们将自动加载,因为 Composer 自动加载器将从供应商加载 QuickBooks 文件。这对于 Laravel 以及一般的基于 Composer 的应用程序都是正确的——与 Laravel 的唯一区别是没有专门为 Laravel 包 ServiceProvider 编写的这个SDK,但这没关系。
  2. QuickBooks 库会尝试自动加载任何以 'QuickBooks' 开头的 class,因此您最好创建一个 QuickBooks 文件夹 用于您的控制器 class。这更像是 'gotcha' 并且一直是 pointed out in the repo issues
  3. 您收到 Driver/.php 错误的原因是您没有指定 QBO_DSN,或者指定不正确 - 您传递给初始化的这个 DSN 环境变量是在 SDK 代码中从 运行 到 parse_url(),出现 falsenull 并破坏自动加载程序以进行初始化。如果将其设置为正确的连接字符串(例如 mysqli://username:password@host:port/database 并注意 port 必须 为数字,否则将被视为格式错误),它将正确处理 DSN并继续加载页面。请注意,初始化将尝试解析和获取主机的网络地址,因此您不能只在其中放置一个虚拟值并期望它起作用 - 这需要先存在。
  4. 您混合了环境变量和应用程序配置,但没有正确使用它们中的任何一个。如果您希望您的数据库连接字符串 (a.k.a.QBO_DSN) 以特定方式构建到应用程序配置设置 qbo_mysql_connection 中,那么您在尝试 using the configuration setting 时应该 initialise/load/etc。而不是使用 env('QBO_DSN'),您应该使用 config('app.qbo_mysql_connection') 从您的应用程序设置中加载构建的版本。通常,您根本不会将如此多的环境变量加载到控制器中 - 这应该由应用程序处理,然后控制器调用应用程序配置,因此它不知道它们是如何定义的。
  5. 您也不需要 require 应用配置文件中的任何内容 - 该文件仅用于设置配置变量。
  6. 由于 QuickBooks SDK 的名称不正确spaced (yet),所以没有很好的 PSR-4 加载方式(和 use-ing) classes,但在文件顶部使用 use 子句(例如 use QuickBooks_Utilities;)仍然是一个好习惯,这样您就可以使用 classes 而不必担心忘记前面的反斜杠(即不再使用 \QuickBooks_Utilities,仅使用 QuickBooks_Utilities)- 在给定的代码中有几个实例已经忘记了,并且不会工作,因为 Laravel 应用程序是 namespaced 并且会在 App\Http\Controllers namespace 中寻找那些 classes(例如像 "Cannot find class App\Http\Controllers\QuickBooks_Utilities" 这样的错误)。
  7. 缩进 - 选择一种样式(例如制表符、2-space、PSR-2 等)并坚持使用。 运行 phpcs 或其他一些清理工具,在提交到您的存储库或在 SO 上发布之前对所有代码进行清理 - 可读性很重要!

Config/app.php

页脚 中添加此行
require_once '../QuickBooks.php';