Use Memcached in Cakephp 3 - php

How can I access a memcached database in cakephp without using the CakePhp MemcachedEngine.php?
When I try to create a new Memcached() Object, Cake doesn't recognize that I need the php class and gives me an error like:
Class 'App\Controller\Memcached' not found
I don't want to use CakePHP's implementation of MemcachedEngine, because we had some issues with it. Is there any Memcached.php File which I can include with e.g. require_once()...?

You can try put at the top of your class: use \Memcached; or use new \Memcached().

Related

Using ReflectionClass in CakePHP 4.0.4

I'm trying to integrate the Playfab PHP SDK into CakePHP 4.0.4,
but Cake doesn't like the following line (included in the SDK example):
$apiReflection = new ReflectionClass("PlayFab" . $PlayFabApi . "Api");
it outputs the following error:
Class 'App\Controller\ReflectionClass' not found
As far as I know ReflectionClass is native class in PHP, so I understand CakePHP is using some kind of PHP subset that doesn't allow ReflectionClass, probably because this class allows reverse engineering and so on.
Is there anything else I am missing?
and most important, how can I make new ReflectionClass() constructor work without compromising the whole project security?
As usual: if you want to instantiate a class from the global namespace, while your current code is in another namespace, you have to prefix the class name using a backslash. Try to use :
$apiReflection = new \ReflectionClass
After some more research I've found the solution was as simple as including:
use ReflectionClass;
use ReflectionException;
use ReflectionMethod;

Trying to add a library to Symfony using composer

I am trying to add the following library (link) to my Symfony project using composer.
I have run
composer require jaggedsoft/php-binance-api
without a problem but I am getting the following error when loading the page.
Attempted to load class "API" from namespace "App\Controller\Binance".
Did you forget a "use" statement for another namespace?
public function index(){
require '../vendor/autoload.php';
$api = new Binance\API("<api key>","<secret>");
}
Now i am guessing that I need to add a use statement but I am a bit stuck on what it is that I need to add.
To reiterate what I suggested in the comments (options 1 and 3 below):
The namespace of your file - although not explicitly written in your post - is:
App\Controller
without any use statement, the new Binance\API(...) is interpreted as:
App\Controller\Binance\API
which is the concatenation of App\Controller (your namespace) and Binance\API (the classname used).
which of course is not what you want to use, since this is something you tried to include from the binance package. This also explains the error message
Attempted to load class API from namespace App\Controller\Binance. Did you forget a use statement for another namespace?
which is exactly what went wrong. PHP tried to load App\Controller\Binance\API which is class API from namespace App\Controller\Binance.
Now there are A few different ways to fix this:
add use Binance; in the header of your file, then you can use new Binance\API(...)
add use Binance\API; in the header of your file, then you can use new API(...)
don't add a use statement, then you can use new \Binance\APi(...)
add use Binance as Something; in the header of your file, then you can use new Something\API(...); (aliasing the parent namespace Binance as Something may resolve name collisions)
add use Binance\API as BinanceApi; in the header of your file, then you can use new BinanceApi(...);
You decided to use option 1. Which is preferable, if the class (API in this case) isn't very expressive or unique on its own - so is option 5. However, if you use more classes from the Binance namespace, option 1 is preferable.
Option 3 will always work (and might seem preferable if any of the other options seem overkill for some reason) - you can actually get by without any use statement at all, but it can get frustrating to read and write.
Overall, all options are viable and it comes to taste which one to use. Mixing those options may lead to confusion. Inside Symfony I've mostly seen option 2 with the occasional alias (use ... as ...;), especially when using DoctrineORM annotations or when extending some Class which has the same Class name but in a different namespace:
namespace [package1];
use [package2]\[ClassName] as Base[ClassName];
class [ClassName] extends Base[ClassName] { ... }
I hope this explanation helps. The php docs for namespaces are actually helpful, when you understand the core concept of namespaces.

PHP: forcing use of extended class in different namespace by core class / function

Background (although my problem can be generalised): I would like to integrate the Mongo core classes with PhpRbac (role based authentication) to add an additional layer of security to limit access to specific databases and collections. e.g. if the code attempts to access the collection "dbname.foo.bar.baz" it will check for existence of the PhpRbac permission "/mongo/dbname/foo/bar/baz" and ensure that the current user has permission.
I would like to force the core MongoClient::selectDB() function to return my extended version of MongoDB rather than the core MongoDB as it usually does.
e.g.
(1) Define the extended version of MongoDB
namespace MyUniqueNamespace;
class MongoDB extends \MongoDB {
public function __construct(){
die("We're definitely using the extended version!");
}
public function someStandardFunction(){
authoriseOrThrowException();
return parent::someStandardFunction();
}
}
(2) Force the core MongoClient (without modifying it) to use \MyUniqueNameSpace\MongoDB instead of MongoDB. Using use or use ... as MongoDB does not do the trick :(
use \MyUniqueNameSpace\MongoDB;
$cl = new MongoClient();
$db = $cl->selectDB("dbname"); //would die if it was using the extended function
Can anyone suggest a way of achieving this? PHP can't cast as a different class and I don't want to start rewriting the Mongo classes because this is a general problem that I'll face when integrating PhpRbac with other functionality.
Thanks for your help :)
You should add following use statement in your MongoClient class instead of where you're calling it:
use \MyUniqueNameSpace\MongoDB;

Load a class with a different name than the one passed to the autoloader as argument

basically, I have the following problem: I want to make use of PHP's new namespace features. Unfortunately, I'm running a PHP version (5.3.2) in which namespace-autoload-support for linux still seems buggy and does not work (PHP should be able to load the class file automatically by its namespace without having to use a custom autoloader, but that doesn't work).
What I want to achieve is to write an autoloader that I can simply remove as soon as the php's namespace features work correctly (there seems to be a speed advantage when not using a custom autoloader) with having to change as less code as possible afterwards.
So I have a call like this:
$filereader = new system\libraries\file\XML();
which gets passed correctly as the string "system\libraries\file\XML" to my autoload-function. I can load the corresponding file "system/libraries/file/XML.class.php". However, the class in there will be named
class XML { ... }
(or something different than "system\libraries\file\XML") and so have a different name than the one by which PHP will try to load it. So is there an easy way to load that class ("XML") which has a different name than the name which I pass to the autoloader function? Can I perhaps do something in the autoloader to achieve that behaviour? (I'm using spl_autoload_register).
I know that even if it worked out I would still not be able to use all features of namespacing, since a (simple) autoloader would not respect the "use namespace" directive and I would still have to use rather long names for loading a class. However, if I understood PHP's namespace-features correctly, I could leave the code as it is when I later switch to using native namespace support instead of my autoloader.
If what I try to do does not make sense at all in your opinion or if I misunderstood namespaces, please tell me (- I have not used PHP's namespace features yet).
I would load the file (which creates the XML class) and then alias the XML class to the properly namespaced system\libraries\file\XML class:
class_alias('XML', 'system\libraries\file\XML');
More generally:
class_alias(basename($class), $class));
Though I'm not quite sure whether class_alias can alias to namespaced classes...

Loading custom classes in CodeIgniter?

Just starting to use CodeIgniter, and I'd like to import some of my old classes for use in a new project. However, I don't want to modify them too much to fit into the CI way of doing things, and I'd like to be able to continue to use NetBeans' autocomplete functionality, which doesn't work too well with CI.
So, what is the best way to load custom classes & class files into CodeIgniter without having to use the library/model loading mechanisms?
I apologise if this is something I should be able to find quickly, but I can't seem to find what I'm after. Everything I see is just telling me how to go through CI.
To do it codeigniter way, place your custom classes in libraries folder of codeigniter. And then use it by adding that class as library in your controller like this:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Someclass {
public function some_function()
{
}
}
/* End of file Someclass.php */
using in controller:
$this->load->library('someclass');
checkout complete article at http://www.codeigniter.com/user_guide/general/creating_libraries.html
Libraries are easy to write but they have a few restrictions. Constructors can only take an array as a parameter and it's assumed that only one class will exist per file.
You can include any of your own classes to work with them however you want, as this is only PHP ofc :)
include APPPATH . 'classes/foo.php';
$foo = new Foo;
Or set up an __autoload() function in your config.php (best place for it to be) and you can have access to your classes without having to include them.
I'd say you at least write a wrapper class that could require the classes and instantiate the objects and make them accessible. Then you could probably autoload such library and use it as needed.
I would recommend that you at least tried to have them fit in the CI way, as moving forward this will make you life much more easy. I've been in kind of the same position and learned just this along the way.
require_once(PHYSICAL_BASE_URL . 'system/application/controllers/abc.php');
$report= new abc();
Next use the function detail in abc contoller:
$mark=$report->detail($user);
If you're just starting to use CodeIgniter, maybe you ought to check Kohana (http://kohanaframework.org/). It is very similar to CodeIgniter in many ways but it loads classes in the normal way (using new ClassName()) so Netbeans' autocompletion features should works normally.

Categories