If i create two classes in one php file, and define the magic method __toString() for both,which one of them will be executed?Because i have already done this and one of them is executed...i just don't know why?
public function __toString(){
return $this->pla_id." Nom = ".$this->pla_nom.", Rayon = ".$this->pla_rayon.", Gravitation = ".$this->pla_gravitation;
}
public function __toString(){
return $this->sat_id." ".$this->sat_nom." ".$this->sat_rayon." ".$this->sat_rotation;
}
and in another file:
$mars = new Planete(); $mars->setNom("Mars"); $mars->setRayon(3397);
$mars->setGravitation(3.69);
$ph = new Satellite(); $ph->setNom("Phobos");
$ph->setPlanete($mars->getNom()); $ph->setRotation(0.32);
echo $mars;
but only the first one appears!
I forgot to echo the other class instance, my fault!
the answer is to add echo $ph in the last code sorry!!
Related
I have this code:
public function taxesData(Product $product)
{
$taxes = \Auth::user()->taxes;
foreach ($taxes as $tax) {
echo "$product->getTax($tax)";
}
}
which on testing gives this error:
Type error: Too few arguments to function App\Product::getTax(), 0 passed in E:\projects\ims\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Concerns\HasAttributes.php on line 411 and exactly 1 expected
However, just a small change makes it works, but I am not able to understand. Why?
public function taxesData(Product $product)
{
$taxes = \Auth::user()->taxes;
foreach ($taxes as $tax) {
echo $product->getTax($tax);
}
}
Please help.
I tried to simplify it for the purpose of posting here... actually i am creating json with html component for a datatable ->
public function taxesData(Product $product)
{
$taxes = \Auth::user()->taxes;
return datatables()
->of($taxes)
->addColumn('check',function($tax) use($product){
if($product->hasTax($tax)){
return "<input type='checkbox' class='input-sm row-checkbox' name='tax[$tax->id]' value='$tax->id' checked>";
}else{
return "<input type='checkbox' class='input-sm row-checkbox' name='tax[$tax->id]' value='$tax->id'>";
}
})
->editColumn('tax', function($tax) use($product){
return "<span class='currencyinput form-control'>
<input id='rate' type='text' name='rate' value='$product->getTax($tax)' required autofocus>
</span>"
})
->toJson();
}
Adding getTax method
public function getTax(Tax $t)
{
if($this->hasTax($t)){
return $this->taxes->find($t->id)->pivot->tax;
}
else{
return $t->pivot->tax;
}
}
public function hasTax(Tax $tax)
{
foreach ($this->taxes as $t) {
if($t->id == $tax->id){
return true;
}
}
return false;
}
It fails because you are not following the correct syntax of echo strings.
This would work:
echo "{$product->getTax($tax)}";
or actually, because you dont' need the quotes for such a simple expression:
echo $product->getTax($tax);
Here's what I've done so far.
Just for simplicity, I've created a sample Model.
// SampleModel.php
public function relatedModels()
{
return $this->hasMany(RelatedModel::class);
}
// this is like an accessor, but since our model doesn't have
// a property called `relatedModels`, Laravel will ignore it
// until later...
public function getRelatedModels()
{
return "Sample";
}
Given the following code, here are the outputs.
$a = SampleModel::find($id);
$a->relatedModels;
// this returns a collection of related models to this model.
$a->getRelatedModels();
// this returns "Sample";
// HOWEVER, when we try to interpolate that member function call.
"$a->getRelatedModels()"
// this throws error that the method `getRelatedModels` must return a relationship.
// I've also tried to add an argument to my existing function to be in-line with your situation.
public function getRelatedModels($a) ...
// this works well
$a->getRelatedModels(1);
// but this, yes, it throws the error as same as what you've got.
"$a->getRelatedModels(1)";
The error pointed out this line in the framework's codebase.
// HasAttributes.php
protected function getRelationshipFromMethod($method)
{
$relation = $this->$method(); // <-- this line
For some reason, doing "$a->getRelatedModels(1)" triggers the __get magic method of the model.
Which branches down to this stack call.
// Model.php
public function __get($key)
{
return $this->getAttribute($key);
}
// |
// V
// HasAttributes.php
public function getAttribute($key)
{
...
return $this->getRelationValue($key);
}
// |
// V
// HasAttributes.php
public function getRelationValue($key)
{
...
if (method_exists($this, $key)) {
return $this->getRelationshipFromMethod($key);
}
}
// |
// V
// HasAttributes.php
protected function getRelationshipFromMethod($method)
{
$relation = $this->$method(); // <-- lastly to this
// $method = "getRelatedModels"
// since our method `getRelatedModels` needs an argument
// this call will fail since it wasn't able to provide an argument.
...
}
That's why you're getting the too few arguments passed exception. I want to investigate further but I have to go home!
I don't know if this is a legit bug for Laravel, but if you do think so, issue it on Laravel's github repository.
UPDATE
I've posted an issue in github and this is one of the comments which truly made sense for me.
This is neither a issue with Laravel, nor with PHP. You are just using the wrong syntax, see it here: https://github.com/laravel/framework/issues/23639
Github user #staudenmeir commented:
"$sampleModel->getRelatedModels()" is equivalent to "$sampleModel->getRelatedModels"."()".
The usage of variables in strings is limited to "$foo" and "$foo->bar". Function calls like "$foo->bar()"
don't work. You can (but shouldn't) use curly braces for that: "{$foo->bar()}"
The better solution is just simple string concatenation:
"text..." . $sampleModel->getRelatedModels() . "more text..."
So that is why the magic method __get is being called.
So here is my case:
I have three functions performing some chemical reactions(synthesis1(), synthesis2() & synthesis3() ).
All of these functions will give an answer or a fail in the results.
They were originally separate scripts but are now in a class.
NB: the functions work fine by themselves, even in the class.
Below is my script to instantiate the class and start the functions.
My problem is that since i am running a reaction which fires all the functions;
i get one 1 correct answer and two fails or three fail at once.
What is the best way to handle the situation.
I want one correct answer and suppress the two fails or just show one fail in case of three fails(all fails). I don't expect three right answers.
P.s. All answers are strings.
<?php
// create an object for class name
$aaa = new synthesis();
$abc = new synthesis();
$abcd = new synthesis();
// call the functions in the class
$synthesis1 = $aaa->synthesis1();
$synthesis2 = $abc->synthesis2();
$synthesis3 = $abcd->synthesis3();
// call the if functions
$searches = array($synthesis1, $synthesis2, $synthesis3);
foreach($searches as $search) {
if ($aaa->synthesis1($search)){
echo 'Match found: ' . $search;
break;
}
elseif ($abc->synthesis2($search)){
echo 'Match found: ' . $search;
break;
}
elseif ($abcd->synthesis3($search)){
echo 'Match found: ' . $search;
break;
}
else{ echo"Please try again or try another reaction";}
}
?>
I don't know why you need to instantiate three different objects if you have three individually named methods.
I would think you might want to add a method to your class to simply run all synthesis methods all at once and return the result. So something like:
class synthesis {
protected $synthesis_methods = array(
'synthesis1',
'synthesis2',
'synthesis3',
// add more methods here if needed
}
public function synthesis1() {
// your method logic here
}
public function synthesis2() {
// your method logic here
}
public function synthesis2() {
// your method logic here
}
public function synthesize_all() {
$result = false;
$i = 0;
while(false === $result && $i < count($this->synthesis_methods)) {
$result = call_user_func(array($this, $this->synthesis_methods[$i]));
$i++;
}
return $result;
}
}
You would then only instantiate a single object. Usage would be:
$synth_obj = new synthesis();
var_dump($synth_obj->synthesize_all());
An easy way to handle this is to use OR logic:
if($aaa->synthesis1($search) or $abc->synthesis2($search) or $abcd->synthesis3($search))
{
echo "Match Found: $search";
break;
}
else
{
echo "Please try again or try another reaction.";
}
<?php
class oopClass{
function __construct($editingtext, $searchfor, $replacewith){
if(!empty($editingtext) && !empty($searchfor) && !empty($replacewith)){
$editingtext = str_replace($searchfor,$replacewith,$editingtext);
echo $editingtext;
}else{
echo 'All Fields Are Required.';
}
}
}
//closing php
The code is working , but as there is no properties of the class are set which is a bad practice, which variables of this code should be set as a class property and why?
There are other things wrong with your code, and it is not the absence of properties. You are constructing an object and in the constructor you output the result. THAT is bad practice.
I'd fix it something like this:
class TextReplacer {
var $search;
var $replace;
function __construct($s, $r) {
$this->search = $s;
$this->replace = $r;
}
function replace($text) {
// your code, using the properties for search and replace, RETURNING the result
return $ret;
}
}
then call like:
$oo = new TextReplacer("bar", "baz");
echo $oo->replace("let's replace some bars in here");
In short:
Nothing wrong with not using properties, if your class is designed like that.
Please use useful class, method and variable names.
Don't do more than one thing in a method ("side effects").
Don't output the result, but return it. It is up to the user of the class to decide what happens to the results.
(most importantly): Think before you code.
It's not necessarily bad practice if the above code is ALL you plan on doing with this code. If you needed to expand its functionality, I might imagine $editingtext could be a property.
class oopClass{
private $editingtext;
function __construct($editingtext, $searchfor, $replacewith){
$this->editingtext = $editingtext;
if(!empty($this->editingtext) && !empty($searchfor) && !empty($replacewith)){
$this->editingtext = str_replace($searchfor,$replacewith,$this->editingtext);
echo $this->editingtext;
}else{
echo 'All Fields Are Required.';
}
}
}
//closing php
Hi Im new to PHP so forgive the basic nature of this question.
I have a class: "CustomerInfo.php" which Im including in another class. Then I am trying to set a variable of CustomerInfo object with the defined setter method and Im trying to echo that variable using the getter method. Problem is the getter is not working. But if I directly access the variable I can echo the value. Im confused....
<?php
class CustomerInfo
{
public $cust_AptNum;
public function _construct()
{
echo"Creating new CustomerInfo instance<br/>";
$this->cust_AptNum = "";
}
public function setAptNum($apt_num)
{
$this->cust_AptNum = $apt_num;
}
public function getAptNum()
{
return $this->cust_AptNum;
}
}
?>
<?php
include ('CustomerInfo.php');
$CustomerInfoObj = new CustomerInfo();
$CustomerInfoObj->setAptNum("22");
//The line below doesn't output anything
echo "CustomerAptNo = $CustomerInfoObj->getAptNum()<br/>";
//This line outputs the value that was set
echo "CustomerAptNo = $CustomerInfoObj->cust_AptNum<br/>";
?>
Try
echo 'CustomerAptNo = ' . $CustomerInfoObj->getAptNum() . '<br/>';
Or you will need to place the method call with in a "Complex (curly) syntax"
echo "CustomerAptNo = {$CustomerInfoObj->getAptNum()} <br/>";
As your calling a method, not a variable with in double quotes.
for concat string and variables, you can use sprintf method for better perfomace of you app
instead of this:
echo "CustomerAptNo = $CustomerInfoObj->getAptNum()<br/>";
do this:
echo sprintf("CustomerAptNo = %s <br />", $CustomerInfoObj->getAptNum());
check http://php.net/sprintf for more details
I'm having trouble accessing a class' variable.
I have the functions below in the class.
class Profile {
var $Heading;
// ...
function setPageTitle($title)
{
$this->Heading = $title;
echo 'S: ' . $this->Heading;
}
function getPageTitle2()
{
echo 'G: ' . $this->Heading;
return $this->Heading;
}
// ...
}
Now when I run the method $this->setPageTitle("test") I only get
G: S: test
What's wrong with the getPageTitle2 function? Heading is public btw. Please help!
Thanks guys!
Now when I run the method $this->setPageTitle("test") I only get
G: S: test
That sounds implausible. Are you sure you're not running:
$this->getPageTitle2();
$this->setPageTitle("test");
PHP - like most programming languages - is an imperative language. This means that the order in which you do things matters. The variable $this->Header is not set at the time where you call getPageTitle2.
If you have "G: S: test"
it means you called getPageTitle2 before setPageTitle !
It looks normal then : I suggest first set then get.
you have to declare the Heading and title out of the function ... i dont know if you already did that
see the order of calling the functions
class Profile {
var $Heading;
// ...
function setPageTitle($title)
{
$this->Heading = $title;
echo 'S: ' . $this->Heading;
}
function getPageTitle2()
{
echo 'G: ' . $this->Heading;
return $this->Heading;
}
// ...
}
I am guessing you are doing something like this:
$profile = new Profile();
$profile->setPageTitle("test");
$profile->getPageTitle2();
and that this would result in the following output:
S: testG: test
and that if you echo $profile you will just get
test
so what do you think is the problem or what are you not accomplishing that you want to?
also I would probably declare $Heading as
private $heading;