how to possible private variable accessible in child class? - oop

I made a programme in oops concenpt there happening a private variable accessing in child class how it is possible. code entered below.....
here uis my code please help me how is it possible private variable in child class or please identify this code is correct or not.
<?php
class student
{
private $sname,$srollno; //private variable
public function Getdata($name,$rollno){
$this-> sname=$name;
$this-> srollno=$rollno;
}
public function Showdata(){
echo "Name :".$this-> sname."<br>";
echo "Rollno:".$this-> srollno."<br>";
}
}
$obj1 = new student;
$obj1-> Getdata("Sandeep","26");
$obj1-> Showdata();
$obj2 = new student;
$obj2 -> Getdata("Vivek","45");
$obj2 -> Showdata();
class teacher extends student
{
//private $tname,$troll;
public function teach(){
$this-> sname="tillu"; //here access private variable
$this-> srollno="12";
}
public function teachShow(){
echo "tname :".$this-> sname."<br>";
echo "troll : ".$this-> srollno."<br>";
}
}
$obj3 = new teacher;
$obj3-> teach();
$obj3-> teachShow();
?>

Related

how to mock and test inside/outside get and set methods?

I dont know why but Im always getting NullPointer and no idea why and how exactly this test should looks like. Its about method: webServiceTemplate():
#Configuration
public class ErdConfiguration {
#Autowired
private EJwtProperties eJwtProperties;
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
// this package must match the package in the <generatePackage> specified in pom.xml
marshaller.setContextPath("erdUserRoles.wsdl");
return marshaller;
}
public WebServiceTemplate webServiceTemplate() {
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
webServiceTemplate.setMarshaller(marshaller());
webServiceTemplate.setUnmarshaller(marshaller());
webServiceTemplate.setDefaultUri(eJwtProperties.getRoles().getErdServiceUri());
return webServiceTemplate;
}
}
and EJwtProperties class which it uses:
public class EJwtProperties {
private Map<String, String> claims = new HashMap<>();
private String signingKey;
private SourceTokenConfig sourceToken = new SourceTokenConfig();
private RolesConfig roles = new RolesConfig();
private List<String> generateEjwtRoles = Collections.emptyList();
private boolean cacheDisabled = false;
#Data
public static class SourceTokenConfig {
private boolean embedSourceToken = false;
private String embeddedTokenClaimName = "source-token";
}
#Data
public static class RolesConfig {
private boolean rolesEnabled = false;
private String rolesClaimName = "roles";
private String erdAppId;
private String erdServiceUri;
}
}
My code so far looks like this and got null pointer while Im trying to check getRoles() in when-thenReturn :
#Mock
private EJwtProperties eJwtProperties;
#InjectMocks
private ErdConfiguration underTest;
Jaxb2Marshaller marshaller;
#BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
#Test
void webServiceTemplateTest() {
EJwtProperties.RolesConfig roles = new EJwtProperties.RolesConfig();
roles.setErdServiceUri("testErdServiceUri");
eJwtProperties.setRoles(roles);
underTest = new ErdConfiguration();
when(eJwtProperties.getRoles()).thenReturn(roles); //this one passed
when(eJwtProperties.getRoles().getErdServiceUri()).thenReturn(roles.getErdServiceUri()); //here nullPointer
// underTest.webServiceTemplate(); //this is what I was planning to do next
//assertEquals(underTest.webServiceTemplate(), eJwtProperties.getRoles().getErdServiceUri()); //or this
// assertEquals(marshaller, underTest.webServiceTemplate().getMarshaller());
// assertEquals(marshaller, underTest.webServiceTemplate().getUnmarshaller());
}
}
Please keep in mind that I'm still learning tests. Id be thankful for any help. How the hack it should looks like? What am I missing that it return null ? Should I initialize whole properties??

PHPUnit testing a protected static method that uses pdo

I am very new to TDD. I am using phpunit 7.4x-dev. I have the following abstract class that I am trying to develop unit tests for.
use PDO;
abstract class Model {
protected static function getDB() {
static $db = null;
if ($db === null) {
$db = new PDO(ConfigDatabase::DSN, ConfigDatabase::USER, ConfigDatabase::PASSWORD);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return $db;
}
}
I have created the following test to get around the need to deal with the static protected method. And it works if I provide "ConfigureDatabase" class.
use PHPUnit\Framework\TestCase;
class ModelTest extends TestCase {
function newMockClass(){
$stub = new class() extends Model{
function getStaticMethod($methodName){
return self::$methodName();
}
};
return $stub;
}
public function testDatabaseExists() {
$stub = $this->newMockClass();
$db = $stub->getStaticMethod('getDB');
$this->assertInstanceOf(PDO::class,$db);
}
}
Since I do not want my tests to rely on any actual database, How would I fake the calls to PDO.
Following Dormilich suggestion I developed a database interface, just in case I decide later I do not want to use PDO.
interface CRUDImp {
function __construct($datbaseBridgeLikePDO);
...
}
Next I wrote my tests for the constructor. I used setup to make sure I was starting with a fresh mock of \PDO.
class PDOWrapperTest extends TestCase {
private $pdoMock;
private $db;
function setup() {
$this->pdoMock = $this->createMock('\PDO');
$this->db = new PDOWrapper($this->pdoMock);
}
public function testWrapperExists() {
$this->pdoMock->method('getAttribute')->willReturn(\PDO::ERRMODE_EXCEPTION);
$db = new PDOWrapper($this->pdoMock);
$x = $db instanceof CRUDImp;
$this->assertTrue($x);
}
/**
* #expectedException \Exception
*/
public function testNonPDOPassedToConstructor() {
$mock = $this->createMock('\Exception');
$x = new PDOWrapper($mock);
}
...
}
Since PHP is loosely typed I check to make sure that the class passed to the constructor was an instance of \PDO. I implemented the concrete class as follows
class PDOWrapper implements CRUDImp {
private $pdo;
private $dataOutputType = \PDO::FETCH_ASSOC;
public function __construct($pdo) {
if (!($pdo instanceof \PDO)) {
throw new \Exception("PDOWrapper must be passed instance of \PDO");
}
$attr_Errmode = $pdo->getAttribute(\PDO::ATTR_ERRMODE);
if ($attr_Errmode !== \PDO::ERRMODE_EXCEPTION) {
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
}
$this->pdo = $pdo;
}
...
}
Now that I have an independent database wrapper the original Model tests are at the moment trivial and no longer needed. The abstract class Model was modified as follows:
abstract class Model {
protected $database=null;
function __construct(CRUDWrapper $database) {
$this->database = $database;
}
...
}
So for those not familiar with dependency injection I found the following links helpful:
http://php-di.org/doc/understanding-di.html
https://codeinphp.github.io/post/dependency-injection-in-php/
https://designpatternsphp.readthedocs.io/en/latest/Structural/DependencyInjection/README.html
Hope this shortens someone's work.

PHP: OOP constructors signatures

I've class called Books
class Books {
/* Member variables */
var $price;
var $title;
function __construct( $title, $price ) {
$this->title = $title;
$this->price = $price;
}
/* Member functions */
function getPrice(){
echo $this->price ."<br/>";
}
function getTitle(){
echo $this->title ." <br/>";
}
}
then I've added another class which inherit my Book class something like this
class Novel extends Books {
var $publisher;
function getPublisher(){
echo $this->publisher. "<br />";
}
function __construct( $publisher ) {
$this->publisher = $publisher;
}
}
Now I want to invoke Novel class and set all of its properties such as title, price and publisher via constructor so if I do this
$physics = new Books("Physics for High School",1);
$testNovel = new Novel("Test Publisher");
it works great it set the publisher value of my $testNovel object
so how can I set value of Title and price while creating object of it??
even If I try
$testNovel = new Novel("Test Title",4,"Test Pubisher");
here "Test Title" is set as publisher instead of "Test Publisher". Moreover, if I put more values inside signature something like this
$testNovel = new Novel("Test Title",4,"New Pub","","Whatever","","Why it allow");
it does not throw any error why??
When you extend a class that defines a constructor, with a class that defines it's own constructor, you need to call the parent constructor yourself supplying the required parameters. E.g.:
class Novel extends Books
{
// ...
function __construct($title, $price, $publisher)
{
$this->publisher = $publisher;
parent::__construct($title, $price);
}
}
From the manual:
Note: Parent constructors are not called implicitly if the child class
defines a constructor. In order to run a parent constructor, a call to
parent::__construct() within the child constructor is required. If the
child does not define a constructor then it may be inherited from the
parent class just like a normal class method (if it was not declared
as private).

Yii virtual attribute and models

Can a virtual attribute represent a model ? I've read this wiki but don't find answer.
Edit :
The aim is to make my model more explicit for the user.
abstract class BaseDonnee{
protected $info;
public function representingColumn(){
return 'info'; //Please, I'm not sure this is right
}
public function setInfo(){
//I can set the attribute's value
$this->info = Info::model()->find('a condition')->info;
}
public function getInfo(){
return $this->info;
}
}
Edit 2 :
When running the code, I can get an exception :
CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: [Microsoft][SQL Server Native Client 11.0][SQL Server]Nom de colonne non valide : 'info'..
How can I proceed to it work ?
Yes, but it will not be automatically filled by dataprovider etc.
class User
{
/**
* #var Address
*/
private $_address = null;
public function getAddress()
{
return $this->_address;
}
public function setAddress(Address $address)
{
$this->_address = $address;
}
}
Then you can use it:
$user = new User;
$user->address = new Address();
var_dump($user->address->street); // Assuming class Address has street field

Yii::app()->user->id; gets name of user not ID

I am trying to get the user id but no luck so far...
echo Yii::app()->user->id;
and
echo Yii::app()->user->getId();
return the name of user which is weird.
Any idea what is wrong?
Yii::app()->user returns a component CWebUser by default.
When you want to get some additional information about user, you need to extend this component.
Create a file WebUser.php in your components folder. (my example below)
class WebUser extends CWebUser {
/**
* Gets the FullName of user
*
* #return string
*/
public function getFullName()
{
return $this->_model->first_name . ' ' .$this->_model->last_name;
}
}
In your config file find section
'components'=>array(
'user'=>array(
'class'=>'WebUser'
)
)
if there is no this section , just create it. And change 'class'=> to WebUser'.
you should have getId function in user Identity
Or you are can use setState:
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$record=Users::model()->findByAttributes(array('mail'=>$this->username));
if($record===null)
$this->errorCode=self::ERROR_USERNAME_INVALID;
else if($record->password!==md5($this->password."325"))
$this->errorCode=self::ERROR_PASSWORD_INVALID;
else
{
$this->_id = $record->id;
$this->setState('role', $record->active);
$this->setState('mail', $record->mail);
$this->setState('name', $record->name);
$this->setState('surname', $record->surname);
$this->setState('mobile', $record->mobile);
$this->setState('adress', $record->adress);
$record->count_login += 1;
$record->update();
$this->errorCode=self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId()
{
return $this->_id;
}
}
<?php echo Yii::app()->user->name." ".Yii::app()->user->surname; ?>
Use getid function in the Component/Useridentity to get user id and name etc..
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$users=Users::model()->find("email_id='$this->username'");
$this->_id=$users->user_id;
}
public function getId(){
return $this->_id;
}
}
if you want to display it on a views this should do:
echo Yii::$app->user->id;