php - Self function is called without defining it - php

I came across a function, which is being called without defining it anywhere.
No error is shown from intelphense as well.
function I am referring to in the below code is
self::whereIdenityNumber($identityNumber)->exists();
public static function generateUniqueIdentityNumber()
{
$identityNumber = strtoupper(Str::random(10));
while (true) {
$isExist = self::whereIdenityNumber($identityNumber)->exists();
if ($isExist) {
self::generateUniqueIdenityNumber();
}
break;
}
return $identityNumber;
}
There is no problem with the function, just wanted to know how it works.
note:
there is a comment like below in docblock comments. Can this be treated as defining the function?
* #method static \Illuminate\Database\Eloquent\Builder|\App\Models\IdentityUser whereIdentityNumber($value)

That static method seems to be defined at \App\Models\IdentityUser
You must have something like:
Class IdentityUser extends Model{
public static whereIdentityNumber($query){
...
}
}

Related

Fatal error with function

When I create the object SearchResult, I have the constructor call 'setStandardsTable' function that sets variable 'standardsTable'. For some reason I get the error
Fatal error: Uncaught Error: Call to undefined function
setStandardsTable()...
and
Error: Call to undefined function setStandardsTable()...
I tried returning the value after each variable declaration but still nothing. Below is my code.
class SearchResult {
private $keyword, $standardsTable;
/*Constructor */
public function __construct($subject, $keyword) {
//selects the standards table to query based on subject selected
$this->standardsTable = setStandardsTable($subject);
//sets the keyword that will be used to search in the Standards table selected
$this->keyword = $keyword;
}
private function setStandardsTable($subj) {
$standardsSelected="";
switch($subj) {
case "General Math":
$standardsSelected = "math_standards_eng";
break;
case "Algebra I":
$standardsSelected ="algebra_standards_eng";
break;
case "Algebra II":
$standardsSelected = "algebra_two_standards_eng";
break;
default:
$standardsSelected = "math_standards_eng";
}
return $standardsSelected;
}
}
In PHP, you need to use self:: and $this-> to call functions within the same class:
Call to a static function:
$variable = self::SomeStaticFunction();
Call to a non-static function:
$variable = $this->FunctionThatIsntStatic();
...instead of just the function name, which is expected to be in the global namespace.
$this->standardsTable = SomeFunction();
In your case: It's $this->setStandardsTable($subject);
It seems that you just have to do a minor change just replace
$this->standardsTable = setStandardsTable($subject);
With
$this->standardsTable = $this->setStandardsTable($subject);
You can not call directly a member function of Class, you should specify object to call member function.
Simply you can using $this->setStandardsTable($subject)
As others mentions you have to call it with $this
$this->standardsTable = $this->setStandardsTable($subject);
That said something others failed to mention that i think would be of great benifit would be to instead use a factory method. So instead of one overwhelming class you would make many.
interface SearchResultInterface{
public function setKeyword($keyword);
public function getKeyword();
public function getTable();
}
abstract AbstractSearchResult impliments SearchResultInterface{
protected $keyword;
public function setKeyword($keyword)
{
$this->keyword = $keyword;
}
public function getKeyword(){
return $this->keyword;
}
abstract function getTable();
}
class MathResults extends AbstractSearchResult{
public function getTable(){
return 'math_standards_eng';
}
}
class SearchResultFactory {
static function createResult($subj, $keyword) {
switch($subj) {
case "Algebra I":
$Result = new AlgebraResults();
break;
case "Algebra II":
$Result = new AlgebraIIResults();
break;
case "General Math":
default:
$Result = new MathResults();
}
$Result->setKeyword( $keyword );
return $Result;
}
}
Now the really big advantage here is that these look like they would include the lesser classes functionallity. So for example AlgebraII could include stuff from Algebra which could include stuff from Math.
So when you add these other classes in:
class AlgebraResults extends MathResults{
public function getTable(){
return 'algebra_standards_eng';
}
}
class AlgebraIIResults extends AlgebraResults{
public function getTable(){
return 'algebra_two_standards_eng';
}
}
Or you could just extend AbstractSearchResult instead of the level above it, as I have done.
So rather or not this makes sense in your use case, I don't know. But if you have a bunch of functionality you need to impliment, it may be much more streamlined to break this up some.
That said, don't break them up for the sake of breaking them up. If the functionality is generally the same and the code-base is small, then there probably isn't a need. But if you find yourself coding things wildly different for Algebra and Math, then it might make sense to separate them.
The main advantage you git from this, is smaller more focused classes/files (each class should be in its own file). Later it will be easier to add stuff, like if you add Calculus then you just add a new class in and don't have to edit the existing code much. etc.
Hope that makes sense.

Can I Conditionally add a function to my class?

In the framework question 2 answers, themes are an extension of a base theme qa_html_theme_base. In this example I extend the html-function that outputs html.
class qa_html_theme extends qa_html_theme_base
{
function html(){
//Theme goes here
}
}
I want to be able to quickly turn on and off my theme for testing purposes. Is it possible to conditionally extend a class, I tried
class qa_html_theme extends qa_html_theme_base
{
if($debug){
function html(){}
}
}
But it didn't work.
I'm not sure that is possible, this syntax inside a class declaration wouldn't be correct. And if it was, I'm not sure I would recommend it.
But if your function is overriding one of the extended class functions, you could do the following :
class qa_html_theme extends qa_html_theme_base
{
function html(){
global $debug; // added to maintain a correct syntax, but you could as well use $this->debug below, if the value comes from a class property.
if( $debug ){
// your debug code here
}
else {
parent::html();
}
}
}
The only way I can think of to do what you're suggesting (and it's clunky at best) is to conditionally include the class file. So create two class files. We'll call the first theme_html.php and it includes your html() function. The second would be theme_no_html.php and it does NOT have your html() function. This is clunky because you'll have two files to maintain.
Then we do
if($debug) {
include('theme_html.php');
} else {
include('theme_no_html.php');
}
$class = new qa_html_theme();
if my mind is right,
class qa_html_theme extends qa_html_theme_base
{
protected $debug = 1; // or const DEBUG = 1;
/**
* Constructor
*/
public function __construct()
{
if($this->debug){
$this->html();
}else{
// do anything you want
}
}
protected function html(){
//Theme goes here
}
}

Call static method of variable class from anothers class property in PHP

I want to call a static method from a variabe class in PHP. As pointed out several times on SO and because it is general practice, the following works as expected:
class Foo {
public function compile($strClass) {
$strClass::find(); // this works
}
}
Nonetheless I have to call different find methods from $strClass from different methods of a class Foo. That is, why I want to store $strClass in $this->strClass. Unfortunately, this doesn't work:
class Foo {
protected $strClass;
public function __construct($strClass)
{
$this->strClass = $strClass;
}
public function compile($strClass) {
$this->strClass::find(); // this does not work
}
}
Any idea or hint on how to solve that issue?
Update:
As pointed out in the comments, it might be a solution to use call_user_func like this:
call_user_func(array($this->strClass, 'find'), $strParam);
Anyhow, this makes code completion in PHPstorm impossible. Any hints on that? Maybe using code annotation?
You can change your compile method to this:
public function compile($strClass) {
call_user_func(array($this->strClass, 'find'));
}
This class design is flawed. I would try to get rid of the static methods completely, but here is a solution that exploits the fact that you can call static methods on objects:
class Foo {
protected $strClass;
public function __construct($strClass)
{
$this->strClass = new $strClass;
}
public function compile($strClass) {
$this->strClass::find();
}
}
UPDATE: nevermind, this is a syntax error in all current PHP versions, you actually have to do it like this:
$strClass = $this->strClass;
$strClass::find();
And this works with your original code as well, where $this->strClass is a string.

How do I use a variable within an extended class public variable

Have a class that I am using, I am overriding variables in the class to change them to what values I need, but I also not sure if or how to handle an issue. I need to add a key that is generated to each of this URLs before the class calls them. I cannot modify the class file itself.
use Theme/Ride
class ETicket extends Ride {
public $key='US20120303'; // Not in original class
public $accessURL1 = 'http://domain.com/keycheck.php?key='.$key;
public $accessURL2 = 'http://domain.com/keycheck.php?key='.$key;
}
I understand that you cannot use a variable in the setting of the public class variables. Just not sure what would be the way to actually do something like this in the proper format.
My OOP skills are weak. I admit it. So if someone has a suggestion on where I could read up on it and get a clue, it would be appreciated as well. I guess I need OOP for Dummies. =/
---- UPDATE ---
The initial RIDE class has 2 URLs set.
public $accessURL1 = "http://domain.com/index.php";
public $accessURL2 = "http://domain.com/index2.php";
I was to override them so the RIDE class will use my new domains.
I can add the following and it works...
class ETicket extends RIDE {
public $accessURL1 = 'http://mydomain.com/myindex.php';
public $accessURL2 = 'http://mydomain.com/myindex2.php';
}
However, I also want to pass a variable from elsewhere ($key) as a parameter to the URL when I override them so when i call RIDE it has a URL with the value of KEY at the end. (?key=keyvalue)
Your close, if you do not want to allow calling code to change the $key, you can do something like:
class ETicket extends Ride {
public function getKey()
{
return 'US20120303';
}
public function generateUrl()
{
return 'http://domain.com/keycheck.php?key=' . $this->getKey();
}
}
// Calling code example
$eTicket= new ETicket();
// $key is a member of ETicket class, so just call on generateUrl which will
// build and return the url
var_dump($eTicket->generateUrl());
You can also permit calling code to change the key if needed, by adding a public setter/getter:
class ETicket extends Ride {
protected $key;
public function setKey($key)
{
$this->key = $key;
}
public function getKey()
{
return $this->key;
}
public function generateUrl()
{
return 'http://domain.com/keycheck.php?key=' . $this->getKey();
}
}
// Calling code example
$eTicket= new ETicket();
$eTicket->setKey('US20120303');
var_dump($eTicket->generateUrl());
-- UPDATE --
There are a couple of options, you can either append the key to your url as part of the calling code, like this:
$eTicket= new ETicket();
$url = $ride->accessURL1 . '?key=US20120303';
Or, use a method (changed slightly to accept key directly) as I described earlier:
class ETicket extends Ride
{
public function generateUrl($key)
{
return $this->accessURL1 . '?key=' . $key;
}
}
$eTicket= new ETicket();
$url = $eTicket->generateUrl('US20120303');
I guess the point is, you cannot do what you originally asked without which is to concatenate a variable to a member variable initialization.

Returning a static Class in PHP

I am working on a backend project. I need to return a static object withing another static object:
Class this_is_a_very_long_class_name
{
public static function call()
{
return self;
}
public static function script_link($link)
{
//doing stuff here...
}
}
Class Main
{
public static function view()
{
// trying to return View object
return this_is_a_very_long_class_name::call();
}
}
and I am trying to use it like this:
Main::view()::script_link('Some script');
So how can I accomplish that?
P.S.: I am not looking for another solution. I am looking for a answer what I asked.
You don't need that.
Use
View::script_link();
Also this is wrong and misleading view()->script_link because script_link is static
Addendum
If you your problem is your class name length I suggest you to create simple wrapper for this.
function createLink($string){
return VERY_LONG_CLASS_NAME_HELLO_PHP_NAMESPACE::script_link($string);
}
this way you just need to createLink();
in php 5.3: return new View(); (instead of return View::self;).
Manual: http://php.net/manual/en/language.oop5.basic.php#example-159
in php 5.2 use ReflectionClass
I think your syntax on the call is wrong. Since it is static, what you are trying to do would look something like this:
Main::view()::script_link('Some script');
Except that would give you a syntax error. Also, since it is static, you don't need to return anything. You should make it two separate calls:
Main::view();
View::script_link("Some script");
It makes no sense to say "I need to return a static object". If the class is defined, then the static object is present and can be accessed.
You just need a variable to hold the class, as a direct call is invalid syntax
Sample:
Class Main
{
public static function view($type)
{
// return some class
switch ($type) {
case "View 2":
return View2;
break;
default:
return View;
}
}
}
$v = Main::view("normal view");
$v::script_link('test');
Are you looking for functionality as late static binding? Which is supported from PHP 5.3. See here: http://php.net/manual/en/language.oop5.late-static-bindings.php

Categories