Why isn't wordnik's php api loading the required classes? - php

I'm getting the following error with wordnik's php api
Fatal error: Class 'Example' not found in Swagger.php on line 212
I've edited Swagger.php to get it to work, below is the original function
function swagger_autoloader($className) {
$currentDir = substr(__FILE__, 0, strrpos(__FILE__, '/'));
if (file_exists($currentDir . '/' . $className . '.php')) {
include $currentDir . '/' . $className . '.php';
} elseif (file_exists($currentDir . '/models/' . $className . '.php')) {
include $currentDir . '/models/' . $className . '.php';
}
}
The working code I changed to is
function swagger_autoloader($className)
{
include $currentDir . '/models/' . $className . '.php';
}
MORE INFO
My file structure is as follows.
WORDNIK (contains start.php)>>>WORDNIK (contains Swagger.php)>>MODELS (contains Example.php)
I'm using wampserver 2.2 with php 5.4.3
UPDATE/EDIT
Using the following code
function swagger_autoloader($className) {
echo "dirname(__FILE__)= ",dirname(__FILE__);
$currentDir = substr(__FILE__, 0, strrpos(__FILE__, '/'));
echo "currentDir=".$currentDir."</br>";
echo "className=".$className."</br>";
echo "__FILE__=",__FILE__."<br/>";
die();
I get the results
dirname(__FILE__)=D:\wamp\www\wordnik\wordnik
currentDir=
className=Example
__FILE__=D:\wamp\www\wordnik\wordnik\Swagger.php
As suggested by vcampitelli, using either __DIR__ or dirname(__FILE__) works.
MY QUESTION
Why doesn't the original function work?
UNIMPORTANT INFO
For people struggling through the examples, here is my start.php file
<?php
require('./wordnik/Swagger.php');
require('./wordnik/WordApi.php');
require('./wordnik/AccountApi.php');
require('./wordnik/WordsApi.php');
require('./wordnik/WordListApi.php');
require('./wordnik/WordListsApi.php');
$myAPIKey = 'replace_this_with_your_real_api';
$client = new APIClient($myAPIKey, 'http://api.wordnik.com/v4');
$wordApi = new WordApi($client);
$example = $wordApi->getTopExample('irony');
print $example->text;
?>

What does $currentDir return? Have you tried using __DIR__ or dirname(__FILE__) (they are the same) instead of that substr?
If you are using the second example just as you posted (without declaring $currentDir), so that is the problem at your original code: $currentDir is not returning the right folder!
With the original code, which file is being included? Because, actually, I think no one is! Use echo inside those if statements to check that!

The original function doesn't work because it is looking for the position of a UNIX-style forward slash '/', whereas you are on Windows and have backslashes '\'. That's a bug! I'll fix the lib to use dirname(FILE) as you do. Thanks for pointing out the error.

Related

Getting error on server due to anonymous functions issue in PHP 5.2

I'm using "google-api-php-client" library which is working fine on local system but it's giving following error on server as it's version is 5.2!
syntax error, unexpected T_FUNCTION, expecting ')'
So I have two questions here, if we can fix this error by doing some changes in code to make it work with this function? Below is the code of autoload.php
spl_autoload_register(
function ($className) {
$classPath = explode('_', $className);
if ($classPath[0] != 'Google') {
return;
}
// Drop 'Google', and maximum class file path depth in this project is 3.
$classPath = array_slice($classPath, 1, 2);
$filePath = dirname(__FILE__) . '/' . implode('/', $classPath) . '.php';
if (file_exists($filePath)) {
require_once($filePath);
}
}
);
but I'm not sure how to change the above to solve this issue and also is there any library which can run on php version 5.2? As if I use this, it might be possible that it start giving error on some other functionality. Thanks!
It seems your php version not knows about anonymous functions or closures. Try to use named one:
function autoloadGoogleApi($className) {
$classPath = explode('_', $className);
if ($classPath[0] != 'Google') {
return;
}
// Drop 'Google', and maximum class file path depth in this project is 3.
$classPath = array_slice($classPath, 1, 2);
$filePath = dirname(__FILE__) . '/' . implode('/', $classPath) . '.php';
if (file_exists($filePath)) {
require_once($filePath);
}
}
spl_autoload_register('autoloadGoogleApi');
Still, I'm also want to point out, that php version you specifying is very old, so I'm suggesting to really consider option of upgrading.
UPD: 3v4l test

Modifying new code to support PHP5.3

I'm using Roots.io wordpress starter theme. It's coded for PHP 5.5 but the server I'm posting the site on is running PHP 5.3
I need to change this code to be supported by the PHP on the server, but don't know how.
function asset_path($filename) {
$dist_path = get_template_directory_uri() . DIST_DIR;
$directory = dirname($filename) . '/';
$file = basename($filename);
static $manifest;
if (empty($manifest)) {
$manifest_path = get_template_directory() . DIST_DIR . 'assets.json';
$manifest = new JsonManifest($manifest_path);
}
if (WP_ENV !== 'development' && array_key_exists($file, $manifest->get())) {
return $dist_path . $directory . $manifest->get()[$file];
} else {
return $dist_path . $directory . $file;
}
}
The issue is in this line:
return $dist_path . $directory . $manifest->get()[$file];
The [$file] is confusing PHP I think but no idea how to modify this. Any tips? If more code is needed please let me know.
You'll need to split that return as requesting an index from a method call I think started getting supported in 5.4.
Try splitting it out.
$val = $manifest->get();
return $dist_path . $directory . $val[$file];
For reference this is know as array dereferencing. You can find more information about it here.

don't find class in root directory in use of spl_autoload_register

I use of spl_autoload_register for class auto loading like bellow
spl_autoload_register(array($this, 'mainLoader'));
function mainLoader($class) {
$dirs = explode(CLASS_SEPARATOR, $class);
$dirsLen = count($dirs);
$class_name = $dirs[$dirsLen - 1];
if ($dirsLen > 1) {
$paths = array_slice($dirs, 0, $dirsLen - 1);
$path = ROOT . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $paths) . DIRECTORY_SEPARATOR;
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
} else {
set_include_path(get_include_path() . PATH_SEPARATOR . ROOT);
}
spl_autoload_extensions(".php");
spl_autoload($class_name);
}
input class name can be class, dir_class, dir_dir_class, ...
and file can be ROOT/class.php Root/dir/class.php , Root/dir/dir/class.php, ...
but when I run program Error to me
Fatal error: Class 'class' not found in ...
why my auto loader don't work correctly??
note: this function work good in Windows but don't work in Linux Ubuntu 14.04
You're probably using camelCase names to your files.
Unix is case sensitive in file names and spl_autoload will work just with lower case.

spl_autoload_register() in different directories

I have a file that auto loads each of my classes.
This is what it contains:
spl_autoload_register(function($class){
require_once 'classes/' . $class . '.php';
});
require_once 'functions/sanitize.php';
require_once 'functions/hash.php';
But when I require_once this file from another php file that is inside my ajax folder, it will try looking for the classes, the function will look from my classes with the path: main_folder/ajax/classes instead of just main_folder/classes.
Does anyone know how to fix this?
FIX:
spl_autoload_register(function($class){
if (file_exists('classes/' . $class . '.php')) {
require_once 'classes/' . $class . '.php';
}
elseif (file_exists('../classes/' . $class . '.php')) {
require_once '../classes/' . $class . '.php';
}
elseif (file_exists('../../classes/' . $class . '.php')) {
require_once '../../classes/' . $class . '.php';
}
You should simple use this function just once - in the main file (usually index.php) and not in another files.
However if it's not possible (but I don't see any reason when could it be not possible) you can change it for example that way:
spl_autoload_register(function($class){
if (file_exists('classes/' . $class . '.php')) {
require_once 'classes/' . $class . '.php';
}
elseif (file_exists( $class . '.php')) {
require_once $class . '.php';
}
});
Here is a proper way, It should universally work.
EDIT: Make sure to specify levels on dirname in order to find the correct path.
spl_autoload_register(function ($classname) {
$file_realpath = dirname(realpath(__FILE__), levels: 1 /* Change that? */) . DIRECTORY_SEPARATOR . dirname($classname);
$classpath = sprintf('%s' . DIRECTORY_SEPARATOR . '%s.php', $file_realpath, basename($classname, '.{php,PHP}'));
if (file_exists($classpath)) {
echo "Loading <b>$classpath</b>...<br>";
require($classpath);
}
});
You need to know the absolute path to the classes directory, then just use a full qualified path to get there.
Make sure your document root is correctly configured with your http server. Furthermore this is usually solved by routing all requests to index.php and deriving the base path (document root) from there. Here is your code modified:
spl_autoload_register(function($class) {
$resolved = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . $class . '.php';
if(file_exists($resolved)) {
require_once $resolved;
} else {
// make it known to your that a class failed to load somehow
return;
}
})
Here is another implementation that I use for simple projects

PHP Autoload ignorecase

Is there any way to call require_once with some "case insensitive flag" ?
In windows it's okay, but linux is case sensitive. Is there any way to override ?
Thanks
Sure, load
strtolower($className . ".php")
and name your files in lowercase.
Regardless of how you try to load your files, only the lowercase version will ever be loaded.
Just include some where else in you header.php or some other common file.,
<?php
$filename = basename($_SERVER['SCRIPT_FILENAME']);
$request = basename($_SERVER['SCRIPT_NAME']);
if($filename != $request)
die('Case of filename and request do not match!');
?>
I think this may help you resolve your problem. also refer the following location https://superuser.com/questions/431342/linux-both-case-sensitive-and-case-insensitive-and-always-inconvenient
You can use this every time you are loading you auto load the appropriate classes. yu have to change the directories depends on you project. you can you the echo or print_r to print what classes are loaded every time when you are calling something. also all you class names must ot have the same format for example, className.class.php e.g Dashboard.class.php, Category.class.php. you can use
ucwords to make the first letter capital.
function __autoload($className)
{
if (file_exists(__DIR__ . '/../library/' . strtolower($className) . '.class.php'))
{
require_once(__DIR__ . '/../library/' . strtolower($className) . '.class.php');
}
else if (file_exists(__DIR__ . '/../application/controllers/' . strtolower($className) . '.php'))
{
require_once(__DIR__ . '/../application/controllers/' . strtolower($className) . '.php');
}
else if (file_exists(__DIR__ . '/../application/models/' . strtolower($className) . '.php'))
{
require_once(__DIR__ . '/../application/models/' . strtolower($className) . '.php');
}
}

Categories