Basic PHP Class Creation Cause Parse Error: Parse Error - php

<?php
  class TEST{
    public $x=1;
    private $y=2;
    
    public function changeA($val){
      //$this->x = $val;
      echo "X-->".$this->x;
    }
    
    private function changeB($val){
      //$this->y = $val;
      echo "Y-->".$this->y;
    }
  }
  
  $a = new TEST();
  $a->changeA(3);
  #
  $a->changeB(4);
This is really bugging me, I use all the correct syntax but I got error right on the line I do CLASS test.
Parse error: parse error in file.php on line x
Tested:
-Remove vars, functions, new objects. nothing fix it.
====Updated Code above, but still, the same error.
I think there is something wrong with my php... I am now running all different kind of code, even echo return the same error. I think there is some other trouble with my php setup.
===Last update
I was using Ajax to passing value and write into a php file with 755 and public access. It was seem like a kind of process hiccup. Now it functioning correctly. But the example still, really useful. Well, don't know what is the vote down for, its seem make sense to mark reason for vote down as well like the ones who need to vote to close it. So SO can as least know the reason for the vote down. Interesting right? Someone who actually care about improving this.

Class method definitions are not statements, and therefore should not be terminated with ;.
This means that the }; on lines 11, 16 and 17 should simply be } instead.
On another note, I don't know what version of PHP you're using. I'm using PHP 5.5 and got a very clear message:
Parse error: syntax error, unexpected ';', expecting function (T_FUNCTION) in test.php on line 11

It's always good to practice on simple examples to make its own idea about how it works.
This might help to clarify things.
class test
{
public $x;
private $y;
function __construct() {
echo "-- Constructor --<br/>";
$this->changeX(1);
$this->changeY(2);
echo "-- Exiting Constructor --<br/>";
}
public function changeX($val) {
$this->x = $val;
echo "X-->".$this->x."<br/>"; // for debugging purpose only
}
private function changeY($val) {
$this->y = $val;
echo "Y-->".$this->y."<br/>"; // for debugging purpose only
}
public function changeYprivate($val) {
$this->changeY($val); // can call private method here
}
public function getY() {
return $this->y;
}
}
$objTest = new test();
echo "X is ".$objTest->x." and Y is ".$objTest->getY()."<br/>";
$objTest->changeX(3);
$objTest->x = 10; // ok x is public, it can be modified
$objTest->changeYprivate(4);
// $a->changeY(4); // Error : cannot call this function outside the class !
// $objTest->y = 20; // Error : y is private !
// echo $objTest->y; // Error ! Can't even read y because it's private
echo "X is ".$objTest->x." and Y is ".$objTest->getY()."<br/>";
Output:
-- Constructor --
X-->1
Y-->2
-- Exiting Constructor --
X is 1 and Y is 2
X-->3
Y-->4
X is 10 and Y is 4

Related

How do I declare a public function in Laravel 8 Base Controller

am getting the following syntax error, unexpected 'public' (T_PUBLIC), expecting end of file when running this code from Microsoft PHP Graph Tutorial.
(https://learn.microsoft.com/en-us/graph/tutorials/php?tutorial-step=1)
public function loadViewData(){
$viewData = [];
// Check for flash errors
if (session('error')) {
$viewData['error'] = session('error');
$viewData['errorDetail'] = session('errorDetail');
}
// Check for logged on user
if (session('userName')) {
$viewData['userName'] = session('userName');
$viewData['userEmail'] = session('userEmail');
$viewData['userTimeZone'] = session('userTimeZone');
}
return $viewData;
}
( I am relatively inexperienced php person, trying to learn laravel and link to Microsoft Graph. There are many tutorials for linking to Microsoft but none of them work as far as I can see, most are out of date. This was my best hope.
Code not working: note line below is one causing problem. If remove 'public;' then no errors are reported in VSCode
i.e. Note in VSCode it reports no errors in the file if public is removed. As soon as you add it back in you get '
As per the the code is correct but you need to check the class of curly brackets properly close or not .
1 ) when you are using the class and no closing curly brackets properly that time it's given error like unexpected 'public' (T_PUBLIC), expecting end of file .
class yourController extends Controller {
public function loadViewData(){
$viewData = [];
// Check for flash errors
if (session('error')) {
$viewData['error'] = session('error');
$viewData['errorDetail'] = session('errorDetail');
}
// Check for logged on user
if (session('userName')) {
$viewData['userName'] = session('userName');
$viewData['userEmail'] = session('userEmail');
$viewData['userTimeZone'] = session('userTimeZone');
}
return $viewData;
}
}

PHP returns object as null occasionally and unintentionally

We have PHP code in production that sometimes fails with "Call to member function on null", although the same code path executes fine several times before that in one invocation. We have a test that reproduces the error consistently at the same run of the loop.
I already proved that the object gets created correctly in the factory even if it gets returned as null. The factory method must not return null in any case, as indicated in the DocBlock. This question is not related to nullable return types or something like that.
The process does not exceed memory or runtime limitations and I already tried turning off the garbage collector, but no luck. The error happens both in PHP 7.0 and 7.3 on Debian, did not try on other versions or operating systems.
I am not allowed to paste the real code here, but I wrote a simple mockup to explain in more detail. Please keep in mind that this demo code will not result in the error, it is just meant to show the general structure of the program that runs into this fault.
// Three placeholder classes with common methods
class Bender
{
public function common()
{
echo "Bend, bend!" . PHP_EOL;
}
}
class Clamper
{
public function common()
{
echo "Clamp, clamp!" . PHP_EOL;
}
}
class Worker
{
public function common()
{
echo "Work, work!" . PHP_EOL;
}
}
// abstract class with static factory to produce objects
abstract class MomCorp
{
/**
* Factory to create one of several objects
*
* #param string $name
* #return Bender|Clamper|Worker
*/
public static function factory($name)
{
$type = self::managementDecision($name);
switch ($type)
{
case "bender":
$robot = new Bender();
break;
case "clamper":
$robot = new Clamper();
break;
default:
$robot = new Worker();
}
// optional QA works flawlessly here, object is fine all the time!
// $robot->common();
return $robot;
}
public static function managementDecision($name)
{
// irrelevant magic happens on $name here
return "bender";
}
}
foreach (['Rodriguez', 'Angle-ine', 'Flexo', 'Billie'] as $newName)
{
echo "$newName: ";
// The next two lines break after some loops - why?
// The perfectly functional object in factory gets returned as null
$bot = MomCorp::factory($newName);
$bot->common();
}
// SAMPLE OUTPUT
// Rodriguez: Bend, bend!
// Angle-ine: Bend, bend!
// Flexo: Bend, bend!
// Billie: Call to a member function common() on null
Has anyone experienced the same and has any hints on what might cause such an error and how to fix it?

Undefined Variable within class

I recently made a class in PHP
I am trying to declare a variable within class and using str_replace in a function but its show undefined variable
class Status{
$words = array(".com",".net",".co.uk",".tk","co.cc");
$replace = " ";
function getRoomName($roomlink)
{
echo str_replace($words,$replace,$roomlink);
}
}
$status = new Status;
echo $status->getRoomName("http://darsekarbala.com/azadari/");
Any kind of help would be appreciated thanks you
Your variables in the function getRoomname() aren't adressed properly. Your syntax assumes the variables are either declared within the function or passed while calling the function (which they aren't).
To do this within a class, do it while using $this->, like this:
function getRoomName($roomlink)
{
echo str_replace($this->words,$this->replace,$roomlink);
}
For further informations, please have a look into this page of the manual.
Maybe because of the version or something, when I tested your exact code, I got syntax error, unexpected '$words' (T_VARIABLE), expecting function (T_FUNCTION), so setting your variables to private or public should fix this one.
About the undefined varible, you have to use $this-> to access them from your class. Take a look:
class Status{
private $words = array(".com",".net",".co.uk",".tk","co.cc"); // changed
private $replace = " "; // changed
function getRoomName($roomlink){
echo str_replace($this->words, $this->replace, $roomlink); // changed
}
}
$status = new Status;
echo $status->getRoomName("http://darsekarbala.com/azadari/");
Also, since getRoomName isn't returning anything, echoing it doesn't do much. You could just:$status->getRoomName("http://darsekarbala.com/azadari/");.
or change to :
return str_replace($this->words, $this->replace, $roomlink);

PHP pthreads - shared objects

Im searching a safe and fast way to use a shared object.
I asked the question already here: https://github.com/krakjoe/pthreads/issues/470
but obviuously this wasnt the right place.
Trying to share an object (Threaded) with many other contextes (Thread).
All threads are updating this shard object -- they can set own requests and have to respond to requests from others also.
Now that krakjoe responded that lock/unlock wont be available in 7 i got a problem.
I know about :.synchronized but have no idea how to use it to get it working for my needs.
How can i use ::synchronized to write methods like
lock()
unlock()
is_locked() -- check if locked, and if so dont try - just go on and try later
EDIT:
i wrote a (imo) very easy test script.
this script includes no syc/lock/... methods atm.
it should just show what im trying to do.
im still searching a way to use :: to make this shared safe.
code:
<?php
/*
TEST:
create n threads
each will
- Shared::set() its own ref
- check if Shared::exists() its own ref
- Shared::get() its ref back
- call method ::isRunning() at returned val to easily check if is ref or got overwritten by another context
TODO:
using ::synchronized to handle multi-context-access
NOTES:
every method as public to prevent pthreads v2 "Method Modifiers - Special Behaviour"
see: "Method Modifiers - Special Behaviour"
at http://blog.krakjoe.ninja/2015/08/a-letter-from-future.html
*/
class Shared extends Threaded
{
public $data;
public function exists($ident)
{
return isset($this->data[$ident]);
}
public function set($ident, $ref)
{
$return = false;
if(!isset($this->data[$ident])){
$data = $this->data;
$data[$ident] = $ref;
$this->data = $data;
$return = $this->data[$ident];
}
#echo __METHOD__ . '(' . $ident . ') => ' . gettype($return) . PHP_EOL;
return $return;
}
public function get($ident)
{
$return = false;
if($this->exists($ident) === true){
$data = $this->data;
$return = $data[$ident];
unset($data[$ident]);
$this->data = $data;
}
#echo __METHOD__ . '(' . $ident . ') => ' . gettype($return) . PHP_EOL;
return $return;
}
}
class T extends Thread
{
public $count;
public function __construct(Shared $Shared, $ident)
{
$this->Shared = $Shared;
$this->ident = $ident;
}
public function run()
{
$slowdown = true;
$this->count = 0;
while(true){
if($slowdown){
// "don't allow usleep or sleep" : https://github.com/krakjoe/pthreads/commit/a157b34057b0f584b4db326f30961b5c760dead8
// loop a bit to simulate work:
$start = microtime(true);
$until = rand(1, 100000)/1000000;
while(microtime(true)-$start < $until){
// ...
}
}
if($this->Shared->exists($this->ident) === true){
$ref = $this->Shared->get($this->ident);
}
else{
$ref = $this->Shared->set($this->ident, $this);
}
// calling a method on $ref -- if not a ref we crash
$ref->isRunning();
unset($ref);
$this->count++;
}
}
}
echo 'start ...' . PHP_EOL;
$n = 8;
$Shared = new Shared();
for($i = 0, $refs = array(); $i < $n; $i++){
$refs[$i] = new T($Shared, $i);
$refs[$i]->start();
}
while(!empty($refs)){
// print status:
if(!isset($t)or microtime(true)-$t > 1){
$t = microtime(true);
echo 'status: ' . count($refs) . ' running atm ...' . PHP_EOL;
}
// join crashed threads:
foreach($refs as $i => $thread){
if($thread->isRunning() === false){
echo 'T-' . $i . ' stopped after ' . $thread->count . PHP_EOL;
if($thread->isJoined() === false){
$thread->join();
}
unset($refs[$i]);
}
}
}
echo 'no thread running anymore.' . PHP_EOL;
/* output
start ...
status: 8 running atm ...
Notice: Undefined offset: 6 in ...\shared_test.php on line 33
Fatal error: Call to a member function isRunning() on null in ...\shared_test.php on line 82
T-6 stopped after 10
status: 7 running atm ...
Notice: Undefined offset: 4 in ...\shared_test.php on line 33
Fatal error: Call to a member function isRunning() on null in ...\shared_test.php on line 82
T-4 stopped after 35
status: 6 running atm ...
Notice: Undefined offset: 7 in ...\shared_test.php on line 33
Fatal error: Call to a member function isRunning() on null in ...\shared_test.php on line 82
T-7 stopped after 43
status: 5 running atm ...
status: 5 running atm ...
status: 5 running atm ...
[...]
*/
?>
Threaded objects are already thread safe, that is to say that, any time you read, write, check for the existence of, or delete (unset) a member, the operation is atomic - no other context can perform any of the aforementioned operations while the first operation takes place. The same is true for engine handlers that the user is unaware of, everything down to the lowest level is implicitly safe.
Quite re-assuring, however ... This has obvious limits when the logic gets more complex, such as checking the existence of a member before setting or doing something else with it, as you are doing: While the operations on the object are atomic, there is nothing to stop another context unseting a member between the call to isset and the call to read the property/dimension.
This applies to PHP7 (pthreads v3+)
Safety, and integrity are two different things here. When integrity is important you can use Threaded::synchronized in PHP7 to preserve it correctly. In PHP5 you could preserve it also, but the code would be more complicated, as would the explanation.
Your second example should run indefinitely, if I understand it's logic. So I'm using that assumption to construct the correct code, I'm going to make further assumptions about what you might want to do in this endless loop and provide some insight where it seems required.
<?php
class Referee extends Threaded {
public function find(string $ident, Threaded $reference) {
return $this->synchronized(function () use($ident, $reference) {
if (isset($this[$ident])) {
return $this[$ident];
} else return ($this[$ident] = $reference);
});
}
public function foreach(Closure $closure) {
$this->synchronized(function() use($closure) {
foreach ($this as $ident => $reference) {
$closure($ident, $reference);
}
});
}
}
class Test extends Thread {
public function __construct(Referee $referee, string $ident, bool $delay) {
$this->referee = $referee;
$this->ident = $ident;
$this->delay = $delay;
}
public function run() {
while (1) {
if ($this->delay) {
$this->synchronized(function(){
$this->wait(1000000);
});
}
$reference =
$this->referee->find($this->ident, $this);
/* do something with reference here, I guess */
/* do something with all references here */
$this->referee->foreach(function($ident, $reference){
var_dump(Thread::getCurrentThreadId(),
$reference->getIdent(),
$reference->isRunning());
});
}
}
public function getIdent() {
return $this->ident;
}
private $referee;
private $ident;
private $delay;
}
$referee = new Referee();
$threads = [];
$thread = 0;
$idents = [
"smelly",
"dopey",
"bashful",
"grumpy",
"sneezy",
"sleepy",
"happy",
"naughty"
];
while ($thread < 8) {
$threads[$thread] = new Test($referee, $idents[$thread], rand(0, 1));
$threads[$thread]->start();
$thread++;
}
foreach ($threads as $thread)
$thread->join();
?>
So we'll look at the differences, I'll tell you why they are as they are and how else you might write them, you already know that we're not talking about safety now, but integrity, you are afforded the (quite remarkable) assumption that anything you write is "safe", as explained.
The first major difference, is this:
if ($this->delay) {
$this->synchronized(function(){
$this->wait(1000000);
});
}
This is simply a suitable way to make a Thread wait, you wouldn't have to use the Thread itself to synchronize, you could use any Threaded object. The benefit of doing things properly, in case not clear is that, sleep and usleep do not leave threads in a receptive state, using ::wait does.
In the real world, where you really should only ever wait for something, that would be a more complex block, it might (and should) look more like:
if ($this->delay) {
$this->synchronized(function(){
while ($this->condition) {
$this->wait(1000000);
}
});
}
Note: waiting for a timeout is technically waiting for something, however, you might be awoken by something other than the timeout having been reached, and code should be prepared for that.
Such that, another context is able to notify the Thread that it should stop waiting and shutdown gracefully, or carry out some other important action immediately, simply by synchronizing, changing a condition and notifying the Thread.
For predictable code, it's extremely important to get comfortable with how synchronized, wait and notify work.
Next we have our logic for setting and or getting the reference:
$reference =
$this->referee->find($this->ident, $this);
Which invokes this:
public function find(string $ident, Threaded $reference) {
return $this->synchronized(function () use($ident, $reference) {
if (isset($this[$ident])) {
return $this[$ident];
} else return ($this[$ident] = $reference);
});
}
This is badly named, naming things is hard, but you can see that integrity is preserved by synchronization while these grouped operations take place. The same method could also be used to fetch a reference to another object, with a bit of tweaking.
I guess you do something with that particular reference (which is always going to be $this currently). I can't guess what. Moving on ...
I've made the assumption that you'll want to do something with each of these Threads, and you want to preserve the integrity of the data while the entire iteration takes place:
$this->referee->foreach(function($ident, $reference){
var_dump(Thread::getCurrentThreadId(),
$reference->getIdent(),
$reference->isRunning());
});
Which invokes:
public function foreach(Closure $closure) {
$this->synchronized(function() use($closure) {
foreach ($this as $ident => $reference) {
$closure($ident, $reference);
}
});
}
This is how you would do such a thing.
It's worthy of mention that synchronized is not necessarily required here; just as nothing bad will happen if you remove a member from an array you are iterating over, nothing bad will happen if you unset or set or do anything else to an object while iteration occurs.

Fatal error: Cannot use [] for reading

I'm getting this error
Fatal error: Cannot use [] for reading in... on line 26
Checking all the threads that have been made here on this error, I still cannot figure it out. Looking at my code there's nothing I'm doing wrong.
<?php
class Person
{
//Variables for personal information//
private $navn;
private $adresse;
private $postnummer;
private $poststed;
private $telefonnummer;
private $fodselsdato;
public function __construct($navn, $adresse, $postnummer, $poststed, $telefonnummer, $fodselsdato)
{
$this->navn = $navn;
$this->adresse = $adresse;
$this->postnummer = $postnummer;
$this->poststed = $poststed;
$this->telefonnummer = $telefonnummer;
$this->fodselsdato = $fodselsdato;
}
//Creates an array to store education for a person//
private $utdanning = array();
//Function to add education to the array//
public function leggTilUtdanning(Utdanning $utdanning)
{
$this->utdanning[] = $utdanning;
}
}
//Class for education
class Utdanning
{
private $institusjon;
private $studieretning;
private $grad;
private $startet;
private $ferdig;
public function __construct($institusjon, $studieretning, $grad, $startet, $ferdig)
{
$this->institusjon = $institusjon;
$this->studieretning = $studieretning;
$this->grad = $grad;
$this->startet = $startet;
$this->ferdig = $ferdig;
}
}
$person1 = new Person('Dave Lewis', 'Downing Street 14', 0442, 'Northville', 98765432, '17.05.1975');
$utdanning = new Utdanning('Harvard', 'Economics', 'Bachelor', 2013, 2016);
$person1->leggTilUtdanning($utdanning);
?>
The error comes from the line inside the function where I'm trying to add an Utdanning-object to the array. It's funny, cause I tried this very same method of doing it on another project, using the exact same syntax, and it worked perfectly. Furthermore, I don't understand why it says I'm trying to read from the array, when I'm actually adding to it.
Does anyone have an idea what's going on here?
EDIT: I circled the problem and made a more simple version of the code so you can see for yourself.
So, just to mark this solved, I got rid of the problem simply by rewriting the characters inside the method leggtilUtdanning. Appears to have been some sort of character encoding-problem like you pointed out, but I have absolutely no idea how that happened. Anyway, thanks for all the help.

Categories