php pass class to function - php

I have a class with property transof
class translator {
public function transof($phrase) { gives translation of phrase }
}
Now I want to pass an instance of translator to a function:
function parse($part,$class) {
$class->transof($part);
}
$tr = new translator("project","en");
parse("exception",$tr);
Do anyone know how to do this?
I know this example is to simple, and can be easily written without the use of a function, but in my real world example I would like to be able to use a function.
Of course I can use global $tr in the function, and use it inside the function, but I don't like using global.
Thanks in advance

If you do not want to create object in global code to have better maintainability then you need to modify the signature of the function as follows:
function parse($part,$project,$lang) {
$class = new Translator($project,$lang);
$class->transof($part);
}
parse("exception","project","en");

It does what you intend, the object is passed to the function parse. All you need to do is to include the class definition file in or before the php file which contains parse definition or get use of __autoload() function which will include class definition when needed.
You can also define parse this way:
function parse($part, translator $class) {
$class->transof($part);
}
Then code editors as Aptana etc. will know what class this object is an instance of and will be able to provide you with hints concerning your class structure.

Related

Is there a way to dump the method definition in OOP/PHP?

Just wondering if there is any way to dump and view the function/method definition inside the class using the Object name?
I found the way to get the class name and method name as well using an instantiated object name with this function:
public function getObjectMethods(object $obj) {
$className = get_class($obj);
//return $className;
return get_class_methods($className);
}
Also, I could access the properties in the class by using the var_dump; however, is there any way I could see the method/function definition inside the class?
Well AFAIK, there is no such function to see what code written on the function directly. (well, you can get the function line number and read the file with file_get_contents)
You could use Kint as a temporary option. It's uses reflection to deep dive into the class/object/instance.
https://github.com/kint-php/kint
Kint::dump($obj);

Closure::fromCallable for imported function

I'm playing with PHP and some functional style programming.
I'm using the Functional-PHP library but question is generic to PHP (I'm using 7.2).
I try to create a callable from an imported function but what I get is
TypeError: Failed to create closure from callable: function 'pick' not found or invalid function name
Sample code:
use function Functional\pick;
class A
{
public function execute()
{
$pick1 = \Closure::fromCallable('pick');
}
}
PHP use statements define an alias for the rest of the file, but they won't affect a string referencing an imported function or class.
When you say
use function Functional\pick;
it means that in that file, you can call the Functional\pick function just using pick(...). But if you're using a string to reference it then PHP doesn't know to expand the alias.
The quickest way to resolve this is just to use the fully qualified function name when calling fromCallable:
$pick1 = \Closure::fromCallable('Functional\pick');
echo get_class($pick1);
Closure
Alternatively, if you really wanted to use the alias, you could wrap the call a level deeper with another anonymous function:
use function Functional\pick;
$pick1 = \Closure::fromCallable(function (...$args) { return pick(...$args); });
But that's a lot messier, in my opinion at least.
Edit: There's some decent discussion around this in this recent thread in php-externals

import and alias a static method from a class

I am trying to alias a static method from a utility/helper class, the documentation does not give anything regarding static methods and using those defined there doesn't work for static methods (as it seems so).
So say I have this class:
namespace App\Helpers;
class HTTP {
public static function extract_path_from_url( string $url ) {
$parsed_url = wp_parse_url( $url );
if ( ! isset( $parsed_url['path'] ) ) {
return false;
}
return (string) $parsed_url['path'];
}
}
then trying to use it on a different file:
<?php
echo \App\Helpers\HTTP::extract_path_from_url( 'http://example.com/test' );
that one above works
but trying to alias it:
<?php
use \App\Helpers\HTTP\extract_path_from_url as extract_path;
echo extract_path( 'http://example.com/test' );
would output
Fatal error: Uncaught Error: Call to undefined function App\Helpers\HTTP\extract_path_from_url()
even:
<?php
use \App\Helpers\HTTP::extract_path_from_url as extract_path;
echo extract_path( 'http://example.com/test' );
shows this weird error:
Parse error: syntax error, unexpected '::' (T_PAAMAYIM_NEKUDOTAYIM)
Is this possible?
Regards,
Aliasing doesn't magically convert methods into functions, try this instead
<?php
use \App\Helpers\HTTP as extract_path;
echo extract_path::extract_path_from_url( 'http://example.com/test' );
Also (it should go without saying) when you alias this only affects the namespace and class name, not methods of the class. These are generally used for 1 of 2 things. Resolving naming conflicts
use NamespaceOne\Someclass;
use NamespaceTwo\Someclass as SecondClass;
If these were both put without an alias then using
Someclass::method()
Would be ambiguous.
The second thing they can be used for is if you need a lot of classes imported from one namespace. Such as this:
use App\Exceptions\NoFile;
use App\Exceptions\FileSize;
use App\Exceptions\FileType;
throw new NoFile();
throw new FileSize();
throw new FileType();
Can be done this way:
use App\Exceptions as E;
throw new E\NoFile();
throw new E\FileSize();
throw new E\FileType();
Which is not only shorter, but easier to maintain if you change the namespace you have to only change it for the alias and then all is good. So in short it's not really intended for what you want to use it for.
Wrap it
You can always make a wrapper for it:
if(!function_exists('extract_path_from_url')){
function extract_path_from_url($url){
return \App\Helpers\HTTP::extract_path_from_url($url);
}
}
And then call it to your hearts content. Performance wise you do have an extra call by wrapping it, but generally wrappers make it easier to maintain. For example if you rename that method or class, you can change it in the wrapper and everything is good. So there is an argument to be made for either option.
You don't have to check if the function exists, but depending on how your overall system works it may not be a bad idea, so I included it in the example just for the sake of completeness. Personally in a case like this, I don't see any issue putting it right in the same file with the class, just remember to load it. If you are using autoloading the functions won't be included unless you manually load the file or otherwise force it to autoload. Assuming nothing else uses the class first, of course.
One method I have used in the past that I really like, is to make a file named http_functions (classname + _functions) and then add a static method to the class that registers the functions:
class HTTP {
public static function regester_fuctions(){
require 'http_functions.php'
}
}
Then when you call HTTP::regester_fuctions() it autoloads HTTP class and includes all the functional wrappers. In fact I do this very thing in my really super awesome debug print class (queue shameless plug) https://github.com/ArtisticPhoenix/Debug
Just some thoughts, enjoy!
A workaround is to use a namespaced helpers.php file and define 'simple' functions in it, which simply pass through arguments.
// lib/My/Deeply/Nested/Namespace/MyClass.php
<?php
namespace My\Deeply\Nested\Namespace;
class MyClass
{
public static function aVeryUsefulFunction(string $var): string
{
// ...Do some stuff
return $magic;
}
}
// lib/helpers.php
namespace App;
use My\Deeply\Nested\Namespace\MyClass;
function doMagic(...$args)
{
return MyClass::aVeryUsefulFunction(...$args);
}
// templates/my-view.php
<?php use function App\doMagic; ?>
<div>I am doing <?= doMagic('magic') ?>!</div>
Note that by using the spread operator ...$args in my 'pass through' function I can change the requirements of the 'target' function without having to update it in two places.
This will break IDE completion, as it will only know to suggest ...$args rather than string $var. I don't know of a way to docblock a function to tell it to read parameters from another function.
As manual says you can import via use classes, functions and constants. Method of a class (even a static one) is not a function.
So, for example you have:
namespace My\Super\NameSpace;
const MY_CONST = 42;
class MyClass {
public function do() { /* code */ } // this is NOT a function
public static function doStatic() { /* code */ } // this is NOT a function too
}
function my_function() { /* code */ } // this is function
In some other file you can write:
namespace YaNamespace;
use const My\Super\NameSpace\MY_CONST;
use My\Super\NameSpace\MyClass;
use function My\Super\NameSpace\my_function as func_alias;
And that's all items you can import with use.

Accessing Markdown PHP function from within a class

I'm using the Markdown library for PHP by Michel Fortin. Setup is easy and it works great like this:
include_once "markdown.php";
$my_html = Markdown($my_text);
However, I have a class in which I want to pass stuff and 'Markdown' it, like so:
class Test
{
public function showMarkdown ($text)
{
return Markdown($text);
}
}
Obviously, my class is much larger than this, but this is what it boils down to. In my main script I do:
include_once "markdown.php";
$test = new Test();
echo $test->showMarkdown($text);
This returns an error, saying the function 'Markdown' is undefined. That seems obvious, because it's not within the class and I haven't used a scope operator. But when I put the include inside my class and use $this->Markdown or self::Markdown the function is still undefined. I figured that the Markdown function can't be defined inside another function.
So, how can I solve this? I need to do the include, which loads the Markdown function (and the rest of its family) but I want to be able to use it from within my classes.
Thanks for your answers/ideas.
Your example code calls a free function called Markdown (which presumably is defined in markdown.php). You simply need to put the include in the same file as your Test class.
After doing this, you will still call Markdown as a free function, and not as an instance ($this->Markdown) or static (self::Markdown) method.
write
function showMarkdown ($text)
in place of
public function showMarkdown ($text)
and
echo $test->showMarkdown("Hello World");

is there any way to get the information of classname and filename regarding a function in PHP OOPS

i m learning OOPS with JOOMLA... here sometimes i found difficulties to find the method used in some class...
is there any way to find that this function is declared on this class or useful information about that function??
for exmaple
class testModeltest extends JModel
{
function modifyCategory($data = array())
{
$image = $this->imageResize($value);
.......
}
}
now i want to know where the imageResize() function declared/defined first time...means class and file name where this function born
i used magic constact __METHOD__ this retrive useful information inside class . i need such type of function where i just put method name & i get the complete information of that function
i want a below kind of facility( i m sure there are some function in php to get the information about class but don't know )
functionInfo($methodname) // here i just put the function name
which return
Function Name:imageResize
Main class : imageclass
File name where it has been declared : /foldername/filename.php
currenty using(called) in : thisclass::this function
If you are looking for the place where a method was first defined, that should be possible using get_parent_class() - here is a snippet that walks through each class definition - and doing a method_exists() on each class found that way.
However, this will not show where the method has been subsequently overriden, so it may be of limited use to you - in that case, something like Reflection is probably indeed the only way.

Categories