How to include a PHP class using namespaces - php

I haven't quite got my head around namespaces in PHP yet. Nor do I use composer or autoloaders. I understand them, but often have difficulty including them into my own projects.
So I would like to include a package in a Wordpress plugin I am developing, specifically this one https://github.com/elliotboney/thinkific-php
I can include the main file OK, but get the error below when calling a function within that file. I am not sure if its to do with the fact its using namespaces, or just because its trying to include files in the Api sub folder which wont be the correct path once I include the main file into my own code.
Does anyone know how I can include this package to use it it within my own project?
require_once('Thinkific/Thinkific.php');
$think = new \Thinkific\Thinkific([
'apikey' => 'xxxxxxxxx',
'subdomain' => 'yyyyyyyyy',
'debug' => true
]);
$users = $think->users();
$users = $users->getAll();
But this is the error, which shows that the class files and so classes in the Api sub-folder are not loaded.
Fatal error: Uncaught Error: Class '\Thinkific\Api\Users' not found in Fatal error: Uncaught Error: Class '\Thinkific\Api\Users' not found in /mysite/public_html/wp-content/plugins/thinkific/Thinkific/Thinkific.php:51 Stack trace: #0 /mysite/public_html/wp-content/plugins/thinkific/Thinkific/Thinkific.php(36): Thinkific\Thinkific->getApi('\\Thinkific\\Api\\...') #1 /mysite/public_html/wp-content/plugins/thinkific/thinkific.php(50): Thinkific\Thinkific->__call('users', Array) #2 /mysite/public_html/wp-content/plugins/thinkific/thinkific.php(29): Thinkific::thinkific_get_users() #3 /mysite/public_html/wp-includes/class-wp-hook.php(298): thinkific_woocommerce_order_status_completed(Object(WP)) #4 /mysite/public_html/wp-includes/class-wp-hook.php(323): WP_Hook->apply_filters('', Array) #5 /mysite/public_html/wp-includes/plugin.php(515): WP_Hook->do_action(Array) #6 /mysite/public_html/wp-includes/class-wp.php(746): do_action_ref_array('wp in /mysite/public_html/wp-content/plugins/thinkific/Thinkific/Thinkific.php on line 51

Try something like this:
lib.php:
<?php
// Application library 1
namespace App\Lib1;
const MYCONST = 'Hello,';
// Application library 1
namespace App\Lib2;
const MYCONST = 'How are you?';
function MyFunction() {
return __FUNCTION__;
}
class MyClass {
static function WhoAmI() {
return __METHOD__;
}
}
?>
myapp.php:
<?php
require_once('lib.php');
echo App\Lib1\MYCONST . "\n";
echo App\Lib2\MYCONST . "\n\n";
echo App\Lib2\MyFunction() . "\n";
echo App\Lib2\MyClass::WhoAmI() . "\n";
?>

The library which you are using is dependent on composer, the place where you doing composer install there it will generate a vendor/autoload.php, you just need to generate vendor/autoload.php here this file will take care of your autoloading of classes.
require_once 'vendor/autoload.php';
$think = new \Thinkific\Thinkific([
'apikey' => 'xxxxxxxxx',
'subdomain' => 'yyyyyyyyy',
'debug' => true
]);
$users = $think->users();
$users = $users->getAll();

Related

Class 'app' not found in bootstrap\app.php:4 #1 {main} thrown in C:\Users\Logan\Cart\bootstrap\app.php on line 4

I keep getting this error I checked the composer.json file and everything seems to be alright I'm following a tutorial for a shopping cart online in php. Any help would be greatly appreciated it.
I checked a similar question and he corrected in the composer.json file and that's not the issue with my problem.
bootstrap-app.php
<?php
session_start();
$app = new app;
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../app/routes.php';
index.php
<?php
require __DIR__ . '/../bootstrap/app.php';
$app->run();
composer.json
"autoload": {
"psr-4": {
"Cart\\": "app/"
}
},
I've also have dumped the file before and no changes. I'm new to php and I'm just trying to complete this tutorial so I can complete an e-commerce website.
Fatal error: Uncaught Error: Class 'app' not found in
C:\Users\Logan\Cart\bootstrap\app.php:4 Stack trace: #0 C:\Users\Logan\Cart\public\index.php(3): require() #1 {main} thrown in C:\Users\Logan\Cart\bootstrap\app.php on line 4
Edited to include this:
<?php
namespace Cart;
use DI\ContainerBuilder;
use DI\Bridge\Slim\App as DIBridge;
class App extends DIBridge
{
protected function configureContainer(ContainerBuilder $builder)
{
$builder->addDefintions (
['settings.displayErrorDetails' => true,] );
$builder->addDefinitions(__DIR__ .'/container.php');
}
}

Laravel - bindings file for repositories

So I have an App\bindings.php file that I have added to my composer.json file as so:
"autoload": {
"files": [
"app/bindings.php"
]
},
In this file I am trying to set up bindings for my repositories like so:
<?php
function getRepoBinding($id)
{
$repo = "{$id}Repository";
$clientName = strtoupper(config('client.name'));
$implementation = config('app.repo_implementation', 'Eloquent');
$clientOverride = "App\Overrides\\{$clientName}\Repositories\\{$implementation}\\{$repo}";
$repo = class_exists($clientOverride) ? $clientOverride : "App\Repositories\\{$implementation}\\{$repo}";
return $repo;
}
// Repository Interface Bindings
dd(getRepoBinding('Contribution'));
App::bind('ContributionIneterface', getRepoBinding('Contribution'));
However, i run a composer dump-auto and try to run my application and I get the following error:
Fatal error: Uncaught Error: Call to a member function make() on null in /home/vagrant/Code/famsapi/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php:54
Stack trace: #0 /home/vagrant/Code/famsapi/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php(158): app('config')
#1 /home/vagrant/Code/famsapi/app/bindings.php(9): config('client.name')
#2 /home/vagrant/Code/famsapi/app/bindings.php(16): App\getRepoBinding('Contribution')
#3 /home/vagrant/Code/famsapi/vendor/composer/autoload_real.php(55): require('/home/vagrant/C...')
#4 /home/vagrant/Code/famsapi/vendor/composer/autoload_real.php(45): composerRequire03fe235c8b3156f0c5fcebbc0d696734('90f93262f3a0ac8...', '/home/vagrant/C...')
#5 /home/vagrant/Code/famsapi/vendor/autoload.php(7): ComposerAutoloaderInit03fe235c8b3156f0c5fcebbc0d696734::getLoader()
#6 /home/vagrant/Code/famsapi/bootstrap/autoload.php(17): require('/home/vagrant/C...')
#7 /home/vagrant/Code/famsapi/public/index.php(22): require('/home/vagrant/C...')
#8 {main} thrown in /home/vagrant/Code/famsapi/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php on line 54
It seems like it is having with the global config helper method...but im not sure how to fix that. Better yet, if you have an idea of how I can do this another way I am all ears.
It is because you are loading that file before the application starts.
Use it inside your AppServiceProvider

Unable To Call a Class Installed Using Composer

I have installed a PHP wrapper library using Composer. The autoloader seems to be working fine, but I cannot call a class as it says
class 'Diffbot' not found.
I have tried numerous tricks, especially those mentioned in the Composer documentation, but I cannot get it working and I think I must share my problem here.
My composer.json contains the following lines
{
"require": {
"swader/diffbot-php-client": "^0.4.4"
}
}
Directory structure
Vendor
---composer
---guzzlehttp
---react
---swader
---autoload.php
'swader' folder
---diffbot-php-client
---src
---Abstracts
---Api
---Entity
---Exceptions
---Factory
---Interfaces
---Traits
---Diffbot.php
I am trying to call Diffbot class under Diffbot.php, it contains the following namespaces:
namespace Swader\Diffbot;
use Swader\Diffbot\Api\Crawl;
use Swader\Diffbot\Api\Custom;
use Swader\Diffbot\Api\Search;
use Swader\Diffbot\Exceptions\DiffbotException;
use Swader\Diffbot\Api\Product;
use Swader\Diffbot\Api\Image;
use Swader\Diffbot\Api\Analyze;
use Swader\Diffbot\Api\Article;
use Swader\Diffbot\Api\Discussion;
use GuzzleHttp\Client;
use Swader\Diffbot\Factory\Entity;
use Swader\Diffbot\Interfaces\Api;
use Swader\Diffbot\Interfaces\EntityFactory;
/**
* Class Diffbot
*
* The main class for API consumption
*
* #package Swader\Diffbot
*/
class Diffbot
{
/** #var string The API access token */
protected static $token = null;
The autoload_psr4.php file under composer/ folder:
// autoload_psr4.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Swader\\Diffbot\\' => array($vendorDir . '/swader/diffbot-php-client/src'),
'React\\Promise\\' => array($vendorDir . '/react/promise/src'),
'GuzzleHttp\\Stream\\' => array($vendorDir . '/guzzlehttp/streams/src'),
'GuzzleHttp\\Ring\\' => array($vendorDir . '/guzzlehttp/ringphp/src'),
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
);
I am trying to call the Diffbot class from a php script that resides in the same directory as the vendor/ folder in the following manner:
require_once ('vendor/autoload.php');
error_reporting(E_ALL);
$diffbot = new Diffbot();
Edit
I solved my problem. I just added the following lines. I was confused about PHP namespace.
require_once __DIR__.'/vendor/autoload.php';
$foo = new \Swader\Diffbot\Diffbot('foo');
Try
require_once __DIR__.'/vendor/autoload.php';
use Swader\Diffbot\Diffbot;
$diffbot = new Diffbot();
See PHP doc for reference.

error on google app engine with laravel

I've tried to deploy my laravel based projec to gae, but I'm getting a blank screen and this in the error logs
PHP Fatal error: Uncaught exception 'ErrorException' with message 'file_get_contents(/base/data/home/apps/s~random-gae-name/1.380824294377640683/vendor/laravel/framework/src/Illuminate/Exception/resources/plain.html): failed to open stream: No such file or directory' in /base/data/home/apps/s~random-gae-name/1.380824294377640683/vendor/laravel/framework/src/Illuminate/Exception/PlainDisplayer.php:21
Stack trace:
#0 [internal function]: Illuminate\Exception\Handler->handleError(2, 'file_get_conten...', '/base/data/home...', 21, Array)
#1 /base/data/home/apps/s~random-gae-name/1.380824294377640683/vendor/laravel/framework/src/Illuminate/Exception/PlainDisplayer.php(21): file_get_contents('/base/data/home...')
#2 /base/data/home/apps/s~random-gae-name/1.380824294377640683/bootstrap/compiled.php(9292): Illuminate\Exception\PlainDisplayer->display(Object(ErrorException))
#3 /base/data/home/apps/s~random-gae-name/1.380824294377640683/bootstrap/compiled.php(9244): Illuminate\Exception\Handler->displayException(Object( in /base/data/home/apps/s~random-gae-name/1.380824294377640683/vendor/laravel/framework/src/Illuminate/Exception/PlainDisplayer.php on line 21
I don't know what this means.
My php.ini
; enable function that are disabled by default in the App Engine PHP runtime
google_app_engine.enable_functions = "php_sapi_name, php_uname, getmypid"
; Cloud storage buckets that Laravel needs to include files from. By default
; in production the first bucket declared here will be used for app storage.
google_app_engine.allow_include_gs_buckets = "x"
allow_url_include=1
and my yaml file
application: x
module: default
version: 1
runtime: php
api_version: 1
handlers:
- url: /.*
script: public/index.php
- url: /(.*\.(ico|gif|png|jpg|css|js|html|txt|pdf|mp3|eps|svg|ttf|woff|eot))
static_files: public/\1
upload: (.*\.(ico|gif|png|jpg|css|js|html|txt|pdf|mp3|eps|svg|ttf|woff|eot))
It seems that you need to change the storage path to your bucket. App Engine apps can't write to the local file system, so you have to override Laravel's Application class method bindInstallPaths to allow the use of Google Cloud Storage as app/storage/ directory.
Use an inherited class of Illuminate\Foundation\Application and then override bindInstallPaths method.
// MyApplicationClass.php file
class MyApplicationClass extends Illuminate\Foundation\Application
{
public function bindInstallPaths(array $paths)
{
if (isset($_SERVER['APPLICATION_ID']) && !empty($_SERVER['APPLICATION_ID'])) {
if (realpath($paths['app'])) {
$this->instance('path', realpath($paths['app']));
}
elseif (file_exists($paths['app'])) {
$this->instance('path', $paths['app']);
}
else {
$this->instance('path', FALSE);
}
foreach (array_except($paths, array('app')) as $key => $value)
{
if (realpath($value)) {
$this->instance("path.{$key}", realpath($value));
}
elseif (file_exists($value)) {
$this->instance("path.{$key}", $value);
}
else {
$this->instance("path.{$key}", FALSE);
}
}
} else {
parent::{__FUNCTION__}($paths);
}
}
}
Then use this class in bootstrap/start.php instead of original one.
$app = (isset($_SERVER['APPLICATION_ID']) && !empty($_SERVER['APPLICATION_ID']))
? new MyApplicationClass
: new Illuminate\Foundation\Application;
And finally, you have to change the storage path in your paths.php file
// paths.php file
$storage_path = (isset($_SERVER['APPLICATION_ID']) && !empty($_SERVER['APPLICATION_ID']))
? "gs://" . $your_bucket_name . "/storage"
: __DIR__.'/../app/storage';
mkdir($storage_path);
return array (
...
'storage' => $storage_path,
);
I hope it works fine for you.

ZF2: Return JSON only for Ajax Call

I'm trying to learn ZF2. I have a page that uses Ajax to get some data. The ZF2 function should return an JSON string.
<?php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\View\Model\JsonModel;
class DocumentsController extends AbstractActionController {
public function indexAction() {
}
public function getTreeDataAction() {
$json = new JsonModel(array(
'title' => 'Some Title'
));
return $json;
}
}
But I keep getting this Fatal Error:
( ! ) Fatal error: Uncaught exception 'Zend\View\Exception\RuntimeException' with message 'Zend\View\Renderer\PhpRenderer::render: Unable to render template "application/documents/get-tree-data"; resolver could not resolve to a file' in ../vendor/ZF2/library/Zend/View/Renderer/PhpRenderer.php on line 451
I have been searching around for this error and the best way to make ajax calls in ZF2, however results for ZF1 or ZF2 betas keep coming up and do not work. Thank you for any advice you can give.
Hmm, that error pretty much implies that it tries to access the default rendering strategy, which is quite weird... Have you added the JsonStrategy to your view_manager?
//module.config.php
return array(
'view_manager' => array(
'strategies' => array(
'ViewJsonStrategy',
),
),
)
Furthermore it's a good idea to set the correct accept header for within you ajax calls to only accept application/json content type. With this set, it should actually work. Out of curiousity though, does modules/__NAMESPACE__/view/__namespace__/documents/get-tree-data.phtml exist?
Try something like this...
$response = $this->getResponse();
$response->setStatusCode(200);
$jsonArray = {.....}
$response->setBody($jsonArray);
return $response;
And make sure you add ViewJsonStrategy to your module config as well.

Categories