PostHog namespace issue - php

I installed PostHog in my PHP codebase, and trying to use it by following the tutorial in this link (https://posthog.com/docs/integrate/server/php).
I am attempting to call PostHog::init function as a following:
PostHog::init($apikey,
array('host' => $baseUrl,
"debug" => true)
);
But I am getting error in this line PostHog::init, the error says
"Attempted to load class PostHog" from the global namespace. Did you forget a "use" statement?"
In fact, I am already using the "use" as following "use PostHog\PostHog;", but I am still getting this error. I can confrim that the Posthog library is intall becuase I can read the classess in Poshog library from my codebase.
This is more info about my app:
I use Symfony framework 5 and the app is deployed in docker. I use PHP 7.4 and posthog/posthog-php": "2.1.1".
I checked the vendor folder and PostHog is there (see photo attached)
I implemented service call PosthogHandler where I use PostHog functions (like init, capture and etc). I am calling functions' services from controller. But the issue is that the error appear in the PosthogHandler constructor in line PostHog::init, at PostHog initialisation stage. This is my PosthogHandler service class:
<?php
declare(strict_types=1);
namespace App\Posthogs;
use PostHog\PostHog;
use App\User\User;
class PosthogHandler
{
public function __construct($env, string $key, string $baseUrl)
{
PostHog::init($key,
array('host' => $baseUrl,
"debug" => true)
);
}
public function addEvent(string $eventName, User $user){
PostHog::capture(array(
'distinctId' => $user->getId()->id(),
'event' => $eventName
));
}
}
Any help, why I am getting above error?

The error indicates that your class file could not be autoloaded properly. You might want to check first that PostHog is present in vendor/autoload.php by creating a test file to check
<?php
require_once 'vendor/autoload.php';
var_dump(class_exists('Posthog\Posthog'));
If not you should try this command
composer dump-autoload

It works!
I have three vendor folders in (1) Frontend (1) Controller (3) Services.
Before, I only installed the PostHog library in services folder where I use PostHog functions. This didn't seem working despite the posthog lib appeared in vendor folder.
What it makes work and the error disappears when I installed the posthog lib in controller folder. I don't use posthog in controller at all, I am not sure why I need to install the posthog lib in controller folder in order to work. But eventually it works!

Related

Error: "Your Application class does not have a bootstrap() method. Please add one."

I recently started building an application, locally, using CakePHP 4.X. I installed Composer and successfully installed the CakePHP Authentication and Authorization plugins using it. Now, I'm trying to move on to some community-developed plugins such as
https://github.com/FriendsOfCake/bootstrap-ui
https://github.com/gutocf/page-title
https://github.com/dereuromark/cakephp-feedback
I'm able to install all of the plugins okay but the issue arises when I try to load the plugins. Per the instructions on each of the plugin Git pages, I try to load the plugin from my CLI using the line
bin\cake plugin load BootstrapUI
(I'm on Windows hence the backslash)
I am returned the following message in all cases:
Your Application class does not have a bootstrap() method. Please add one.
My src/Application.php file looks like this
class Application extends BaseApplication
public function bootstrap() : void
{
// Call the parent to `require_once` config/bootstrap.php
parent::bootstrap();
if (PHP_SAPI === 'cli') {
$this->bootstrapCli();
} else {
FactoryLocator::add(
'Table',
(new TableLocator())->allowFallbackClass(false)
);
}
/*
* Only try to load DebugKit in development mode
* Debug Kit should not be installed on a production system
*/
if (Configure::read('debug')) {
$this->addPlugin('DebugKit');
}
// Load more plugins here
$this->addPlugin('Authorization');
$this->addPlugin('Authentication');
$this->addPlugin('BootstrapUI');
}
Your Application class is missing an { after class Application extends BaseApplication but I guess it was pasted/edited incorrectly here.
Your command seems to work because I see the plugin $this->addPlugin('BootstrapUI') already added in the file.
Make sure to be on the correct path (in the root of your app) when you execute the CLI command:
bin\cake plugin load BootstrapUI
You can manually add the plugins in the bootstrap() method without CLI.

HybridAuth 3.0 - fresh install - getting: Class 'Hybridauth\Hybridauth\Provider\Facebook' not found

all. I've installed HybridAuth 3.0 and went step-by-step through the Install instructions using composer. I've used the example code and am able to get an initial HybridAuth class instantiated. However, when I continue on to the example with using the Facebook provider class, I'm getting the error, "Class 'Hybridauth\Hybridauth\Provider\Facebook' not found". I'm also using this in a Drupal 7 environment but have other classes like this that autoload just fine so I'm hopeful that little extra detail has no bearing on the problem.
I tried this both with the composer autoloader and the basic autoloader included with the library (as described in the Installation instructions). They both have the same error when attempting to find the Facebook class which is down in the /src/Provider directory. It does this for other classes as well.
That said, using the Hybridauth\Hybridauth "unified interface" works fine and is my current workaround as it allows one to work with multiple providers at one time. But I'm wondering what I'm doing wrong to not be able to load a specific provider as shown in their Introduction documentation.
This works:
// Include Composer's autoloader
include 'vendor/autoload.php';
// Import Hybridauth's namespace
use Hybridauth\Hybridauth;
// Now we may proceed and instantiate Hybridauth's classes
$instance = new Hybridauth([ /* ... */ ]);
This gives an error:
// Include Composer's autoloader
include 'vendor/autoload.php';
// Import Hybridauth's namespace
use Hybridauth\Hybridauth;
$adapter = new Hybridauth\Provider\Facebook([ /* ... */ ]);

Cannot redeclare class error in Laravel but works fine in native php

I am using Alchemy API for filter out some data. Everything works fine in the native code. But when i used it in my Laravel Controller it throws Cannot redeclare class. My controller,alchemyapi.php and example.php are in the same directory. Here is how i include alchemyapi.php in native code
<?php
require_once 'alchemyapi.php';
$alchemyapi = new AlchemyAPI("MY API KEY"); ?>
But when i include it in the controller it throws my the error. is there something i am missing ?
require_once 'alchemyapi.php';
$alchemyapi = new AlchemyAPI("MY API KEY");
The native code(example.php) works well without any issue. But in laravel controller it throws a error saying Cannot redeclare class AlchemyAPI
in alchemyapi.php line 20
Instead of using require_once use namespace in your alchemyapi.php and then use use for same namespace in your MyController
alchemyapi.php
<?php
namespace App\Http\Controller;
class AlchemyApi {
//your code
}
MyController.php
<?php
namespace App\Http\Controller;
use App\Http\Controller\AlchemyApi;
class MyController {
$alchemy = new AlchemyApi("Your_api_key");
}
OK, so what I think is happening is that alchemyapi.php is somehow already being included by the composer autoloader.
Try this.
Create the directory lib in the root of your project.
Move alchemiapi.php into lib.
Under the "autoload" section in your composer.json add the following code. Make sure the JSON is valid:
"files": [
"lib/alchemyapi.php",
],
Run composer dump-autoload. If it errors, your composer.json is invalid or you haven't put the file in the correct place.
Delete require_once 'alchemyapi.php'; from your controller.
When dealing with composer, this is how you deal with classes in the global namespace. After running composer it scan those directories in app for PSR-4 classes.
I can't be sure but I think that composer is looking for it and you are also manually requiring it. That would explain why PHP thinks you are redeclaring the class.

Fatal error: Class 'PHPUnit_Framework_TestCase' not found in dbunit\PHPUnit\Extensions\Database\TestCase.php on line 24

I want to write tests for MySQL Database. When I try to extend the database extension, it gives me the above error in title:
class FixtureTestCase extends PHPUnit_Extensions_Database_TestCase
Note: I have installed PHPUnit globally and I can access it through phpunit in cmd. I have latest PHPUnit 4.5.1.
I also installed Dbunit globally through composer:
composer global require phpunit/dbunit
Any help will be much appreciated. I've used PHP 5.4.
For referring to classes that are located within the global namespace, you can simply prefix them with a backward ( \ ) slash.
Try with this:
class FixtureTestCase extends \PHPUnit_Extensions_Database_TestCase
With the leading backward ( \ ) slash, PHP knows that we are referring to the PHPUnit_Extensions_Database_TestCase class in the global namespace, and located that one.
More info here
Hope this help.
It just might be the version of DBUnit. For example I'm using PHPUnit 4.8 and it works with DBUnit 1.4.
I had the above error when I was using composer with "phpunit/dbunit": ">=1.2" and I ended up with DBUnit 2.0.
Test your DB how? Through an API you created or direct accesses to DB? i would recommend you to write an API to access your DB and then write the tests to the API.
for exemple if you want to insert a user you call your web-server address (localhost:3000) or something you have and then call /users through POST to insert and make the routes to that.
I would suggest using LARAVEL for that.

Creating a new ServiceProvider / Facade as a package in Laravel 5

Introduction
I've never worked with a framework before (Zend, CakePHP, etc) and finally decided to sit down and learn one. I'm starting with Laravel because the code looks pretty and unlike some other frameworks I tried to install, the "Hello, World!" example worked on the first try.
The Goal
For the time being, I want my app to do something very simple:
User submits a request in the form of: GET /dist/lat,lng
The app uses the remote IP address and MaxMind to determine $latitude1 and $longitude1
This request path is parsed for $latitude2 and $longitude2
Using these two positions, we calculate the distance between them. To do this I'm using Rafael Fragoso's WorldDistance PHP class
Since I plan to re-use this function in later projects, it didn't seem right to throw all of the code into the /app directory. The two reusable parts of the application were:
A service provider that connects to MaxMind and returns a latitude and longitude
A service provider that takes two points on a globe and returns the distance
If I build facades correctly then instead of my routes.php file being a mess of closures within closures, I can simply write:
Route::get('dist/{input}', function($input){
$input = explode( "," , $input );
return Distance::getDistance( GeoIP::getLocation(), $input );
});
What I've tried
Initial Attempt
For the first service provider, I found Daniel Stainback's Laravel 5 GeoIP service provider. It didn't install as easily as it should have (I had to manually copy geoip.php to the /config directory, update /config/app.php by hand, and run composer update and php artisan optimize) however it worked: A request to GET /test returned all of my information.
For the second service provider, I started by trying to mimic the directory structure and file naming convention of the GeoIP service provider. I figured that if I had the same naming convention, the autoloader would be able to locate my class. So I created /vendor/stevendesu/worlddistance/src/Stevendesu/WorldDistance\WorldDistanceServiceProvider.php:
<?php namespace Stevendesu\WorldDistance;
use Illuminate\Support\ServiceProvider;
class WorldDistanceServiceProvider extends ServiceProvider {
protected $defer = false;
public function register()
{
// Register providers.
$this->app['distance'] = $this->app->share(function($app)
{
return new WorldDistance();
});
}
public function provides()
{
return ['distance'];
}
}
I then added this to my /config/app.php:
'Stevendesu\WorldDistance\WorldDistanceServiceProvider',
This fails with a fatal error:
FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found
Using WorkBench
Since this utterly failed I figured that there must be some other file dependency: maybe without composer.json or without a README it gives up. I don't know. So I started to look into package creation. Several Google searches for "create package laravel 5" proved fruitless. Either:
They were using Laravel 4.2, in which case the advice was "run php artisan workbench vendor/package --resources"
Or
They were using Laravel 5, in which case the docs were completely useless
The official Laravel 5 docs give you plenty of sample code, saying things like:
All you need to do is tell Laravel where the views for a given namespace are located. For example, if your package is named "courier", you might add the following to your service provider's boot method:
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}
This makes the assumption that you have a service provider to put a boot method in
Nothing in the docs says how to create a service provider in such a way that it will actually be loaded by Laravel.
I also found several different resources all of which assume you have a repository and you just want to include it in your app, or assume you have "workbench". Nothing about creating a new package entirely from scratch.
PHP Artisan did not even have a "workbench" command, and there was no "workbench.php" file in /config, so anything I found related to workbench was worthless. I started doing some research on Workbench and found several different questions on StackOverflow.
After a long time and some experimentation, I managed to get laravel/workbench into my composer.json, composer update, composer install, manually build a workbench.php config file, and finally use the PHP Artisan Workbench command to make a new package:
php artisan workbench Stevendesu/WorldDistance --resources
This created a directory: /workbench/stevendesu/world-distance with a number of sub-directories and only one file: /workbench/stevendesu/world-distance/src/Stevendesu/WorldDistance/WorldDistanceServiceProvider.php
This service provider class looked essentially identical to the file I created before, except that it was in the /workbench directory instead of the /vendor directory. I tried reloading the page and I still got the fatal error:
FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found
I also tried php artisan vendor:publish. I don't really know what this command does and the description wasn't helpful, so maybe it would help? It didn't.
Question
How do I create a new service provider as a package so that in future projects I can simply include this package and have all the same functionality? Or rather, what did I do wrong so that the package I created isn't working?
After two days of playing with this I managed to find the solution. I had assumed that the directory structure mapped directly to the autoloader's path that it checked (e.g. attempting to access a class Stevendesu\WorldDistance\WorldDistanceServiceProvider would look in vendor/stevendesu/world-distance/WorldDistanceServiceProvider)... This isn't the case.
Reading through the composer source code to see how it actually loads the files, it builds a "classmap" - essentially a gigantic array mapping classes to their respective files. This file is built when you run composer update or composer install - and it will only be built correctly if composer knows the details of your package. That is - if your package is included in your project's composer.json file
I created a local git repository outside of my app then added my package to my app's composer.json file then ran composer update -- suddenly everything worked perfectly.
As for the:
It didn't install as easily as it should have
the secret sauce here was first add the service provider to /config/app.php then, second run php artisan vendor:publish

Categories