Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by gizmola

  1. It's something you implement yourself. It's a pattern, not a built in feature of php. If you use the code I provided, making any necessary substitutions to fit your directory structure, you are on your way. As for the structure provided by the webhost, can you have php scripts outside of the php directory? If so, then it doesn't matter if they provided that directory or not. If they force you to have all your php files inside that directory, then that is a pretty crappy hosting solution, but then again we see these all the time. The best practice these days for php development is to develop your project locally, using virtualization with vagrant/virtualbox or docker. Along the way you use git to version control your sourcecode, pushing it to an external repository on github or bitbucket or gitlab. You then deploy to the production server. I don't think that anyone should settle for a host that prohibits you from using whatever project structure your want, even for "free" hosting, but again, I don't know anything about your hosting situation.
  2. This is true, but a better rule of thumb is that a script should never end with a php end tag. So you should always omit it. For the OP, just to explain the reasoning behind this: The PHP interpreter will automagically close off any PHP script or block when a file ends, removing all whitespace. If however, you create a php script with a standard block like this: <?php // Some PHP code ?> // some whitespace here, or even this "comment" which is actually outside the PHP block and will be treated as text by the parser! Now you include this in another script ... and what happens? PHP sees the end block, something after it, and starts output. This was (and probably still is) a frequent cause of the "Headers already sent" error that people encounter when using sessions or trying to use the header() function to set HTTP headers. When non-buffered output is generated by PHP, the HTTP header gets sent first, so at that point it is too late to set a cookie or any other HTTP header. The solution of leaving off the php end tag has been a long time best practice going back to version 5.x at least. This recommendation was formalized in PSR-2 (since deprecated in favor of PSR-12) so you might want to take a look at the other code standard recommendations from PSR-12, as it's a great set of standards and guidelines for writing and formatting your code. There are also tools that integrate with some of the more used PHP code editors that can reformat your code to fit some or all of these standards.
  3. I can't answer you entirely because I don't know what your project directory structure is. With that said a couple of things: An include or require is like a "copy" routine. Whatever code is in the .php being required, is essentially copied into the parent script at that point. So your path *might be right". This is completely wrong: $connection = $php_path.'PDO_Connection_Select.php'; $get_ip = $php_path.'GetUserIpAddr()'; The first line, sets the variable $connection = to a string that looks like a path to your PDO_Connection_Select.php script. Again, you should just be requiring that script, which copies it into config.php. Any functions and variable you set in that script will be available globally at that point, and will also be available to scripts that include config.php. The 2nd line, is again trying to make a string. It looks like you are trying to call the function GetUserIpAddr(). Looking back at your initial question, it appears that is defined in a script in the same php directory. So... this is probably what you want to do if you are moving this all to config.php. //config/config.php $app_root = DIRNAME(__DIR__); $php_path = $app_root . '/php/'; require_once($php_path . 'PDO_Connection_Select.php'); require_once($php_path . 'GetUserIpAddr.php'); With that said, I wouldn't move the requires up into config unless you are certain you need the things in those scripts (functions, variables, classes) in every script in your system. Only you can say for sure. Certainly you can make the path variables. After that you can use them in other scripts as I illustrate here: <?php //In any script, but this path must be correct to load config.php require_once('../config/config.php'); // Now require whatever you want using $php_path to get to the scripts in /project/php. // It doesn't matter where this calling script it. It could 20 directories down in the tree. These computed paths will be correct to things in /php directory require_once($php_path . 'PDO_Connection_Select.php'); require_once($php_path . 'GetUserIpAddr.php'); // Now you can call functions or use variables in those included scripts. $get_ip = GetUserIpAddr(); I hope this explains this for you. Speaking editorially: why do you have a directory named php? Your entire project is made up of php scripts. It's a terrible name for a directory for a php project. Maybe it should be /lib. The directory layout of any project will organize and facilitate some of these features.
  4. That is what this technique does for you. The ONLY script you need to know the relative path to is your config script. All other paths are specified relative to $app_root, as if it was a virtual filesystem. You never need to use .. to traverse up the tree. $app_root will always be the path to the root of your project.
  5. Again this assumes that under your project root directory you have a /config directory, and in that directory you have a config.php file which defines your $app_root variable. I don't know what your project structure looks like, but if you want to require something in a directory named /path/to/project/php then <?php require_once('../../config/config.php'); require_once($app_root . '/php/PDO_Connection_Select.php'); $connection = ... make_your_connection_function(); // this should not be some global you are making in PDO_Connection as a side effect. //If you want a global db connection variable, just create it in the script and by inclusion you can start using it // Again this is a function, so as long as you included its definition you just use it. $get_ip = GetUserIpAddr();
  6. Yes that is the point of it. Within all your scripts you will only ever need to be aware of the relative path from the root of your project. So let's assume you have a directory beneath your project directory named /path/to/project/images. To get a path to that, no matter what script or where all you need to do is have included the config.php, and from there you specify all file paths relative to your project root. // at top of script require_once('../config/config.php'); // now $app_root will be available $imagepath = $app_root . '/images'; This will work for any requires/includes or any actual filesystem paths you need. You only ever need to be concerned with how to require the project/config/config.php script relative to the script you are using it in. I hesitate to bring this up with everything else, but this is an advantage of using the "front controller" pattern that comes with most frameworks. It facilitates MVC and in particular handling routing in your application. You really only have one php script under your webroot, and never run individual scripts directly. The front controller script (which will be index.php) has everything that is not a .css or .js or image file redirected to it, and it parses up the request and figures out how to "route" the request. You create controller scripts that map to routes, and do your actual work. If you were to use most any php framework (symfony, laravel, cakephp, etc) this is how things work, and there are a lot of advantages and problems solved by MVC. With that said, this technique of establishing a reliable app root and working from it, while baked into those frameworks, can be used by any application, assuming you understand what you need to do to use it. Once you start using the config.php script, you will find it is a handy place for putting other things like database connect strings, or making other path variables. For example the same script can be added upon, by just creating the global path strings you want directly in the config script (ie. define $imagepath in the config.php).
  7. Hello Markosjal. I'm sorry to hear of your illness. I very much hope you will make a recovery. In my opinion the best place for all your projects to be is github. If you want some help in keeping those projects viable under the circumstances, you are welcome to use this technique to invite me to your repos: https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-access-to-your-personal-repositories/inviting-collaborators-to-a-personal-repository If you are unable to continue, I can at least carry on finding people to keep your projects moving forward, and perhaps do some cleanup of whatever php libraries you have. Like the forum, my github name is gizmola.
  8. I want to reiterate: exit is only for immediate exit from a script. You should not be using it here. When a script ends it exits and cleans up everything. Don't get in the habit of adding exits when you don't need them. You use exit like you otherwise might use an exception. Mostly you use it for debugging sessions (as die('something') or exit('something') only to remove it when you have figured out your issue. The only exception to that rule is in the case of a header('Location: ...) call. Since that is meant to redirect the browser (yet still requires the browser to act upon the redirect) it is good practice to follow a header('location....) with an exit. As to your problem it is being caused either by an echo, error or some output from the PDO_Connection_Select.php script. Make sure you don't have a php end tag in that script. Otherwise any error will trigger output. Having your code littered with this type of thing is amateurish, hard to maintain and bug prone. $php_scripts = '../../php/'; formalize your primary settings into a script that every script includes, and set a variable or constant in that script which you use everywhere else. Often people will name this file config.php or bootstrap.php. Let's say your project structure is this your_app/ ├─ public/ │ ├─ module1/ │ ├─ js/ │ ├─ css/ ├─ config/ ├─ config.php Inside config.php you will have something like this: <?php $app_root = DIRNAME(__DIR__); // or if you prefer DEFINE('APP_ROOT', DIRNAME(__DIR__)); All you need do in any script is make sure to include the config.php using whatever relative path you have, and from there, you will be able to make new paths using $app_root or APP_ROOT, without ever having to use relative pathing. If it isn't clear, $app_root will always be /path/to/your_app
  9. You don't need to exit from a php script. exit and die are the same function. You use them in functions/methods.
  10. One pro tip: Never have a php end tag (ie. ?> ) in your scripts. It is not needed, and can lead to bugs like this remove all php end tags whenever they are the last thing in a .php file. You can start with looking at PSR-1, and perhaps graduate to PSR-12 if you are looking for some standards to help guide you.
  11. I agree with the prior responses you got. We really can't give you any practical advice when your database logic is in a superclass you didn't provide. Modern PHP apps use composer with a composer.json, an autoloader and PSR-4 compatible namespacing. Some things you are doing that are anti-patterns: Make sure all your methods actually return something. Don't echo out of a method, return the data that you will output. Use templating (whether it's included template scripts you separate, or a full blown template component class system). There is so much modern PHP you can do with namespacing, in terms of class design and interfaces, that also encourage you to use typehinting of all your parameters and return values. Use those features! I didn't include them in this example, but it's not to late to start using them, even if you are only using these techniques and features in code you are adding or revising. An example of your code rewritten to implement a "guard clause" pattern mentioned by Benanamen. Basically, you can just think of these as separating out individual conditions that will cause your function to exit immediately. You move these to the top of your function/method, rather than having them tacked onto the else. This is especially helpful when you have larger nested if-then-else conditions, as it becomes increasingly difficult to see what happens. Typically the condition will use "not" in it, because you will return from the function (or possibly throw an exception) if that condition is true. Your "happy path" code does not need the condition, as it will be reached only if the conditions are met that allow it to be run. public function DeleteThreadFromDataBase($PostID, $UserOfThread, $CurrentUser) { if($UserOfThread !== $CurrentUser) { return "failure"; } $sql = "DELETE FROM `Threads` WHERE id = $PostID"; $result = $this->connect()->query($sql); return "success"; } Which brings us to Dependency injection. Here is an article series on Dependency Injection to help you understand what it is and how to implement it. Here's one example in your code: public function DeleteFileFromServer($UserOfThread, $CurrentUser,$FilePath) { if($UserOfThread == $CurrentUser) { $UploadDirectory = "../upload/" ; $ThumbnailDirectory = "../upload/Thumbnails/" ; $FilePath = $UploadDirectory . $FilePath ; $ThumbnailDirectory = $ThumbnailDirectory . $FilePath ; unlink($FilePath); echo "<P> Upload File Deleted" ; unlink($ThumbnailDirectory); echo "<P> Thumbnail File Deleted" ; } else { echo "<P> You are not the owner of this thread nor a mod" ; } Let's look at all the problems and lack of DRY-ness: You have low level code that handles physical file access Although you call this method "DeleteFileFromServer" it can only delete a file if it is in the hardwired path, and you hardwired in that the file must be a thumbnail type. Your hardwired relative paths could be replaced with constants or configuration variables that are built upon an application home/base constant you make available throughout your app via a bootstrap, or ideally a front controller. In the future you have some other file that needs to be deleted, but in this case you will be rewriting all this code again. Maybe you decide it would be cool if you were to cache images in redis, but now you have all this hardwired logic, so you have to rewrite this routine rather than a generic file deletion routine in a generic file handling class. What should you have? A file handling component (although there are already many that you could just be using via composer) that handles generically storage/saving/removal of files. With DI you would be "injecting" an object of your file handling class. Security At this point, hopefully it follows that security needs to be separated out into its own class. There are many schemes people use, which often have associated database structure. A typical one would be the user-role-permission. Often a usergroup is added so you can have a pre-set grouping of roles (and associated permissions) rather than having to build that up for each user. So you might have these roles in your system: admin moderator user unconfirmedUser guest You can then have an admin group which includes all 4 roles (and thus all associated permissions). This also makes it possible to change your scheme around. For your question, the important thing is that you have a granular permission type. Not all permissions can be resolved via the relationships as in your example where the rule is that "can-delete-own-thread". In the future you plan to implement a "can-delete-thread". Again, keeping in mind the ideas of Dependency Injection, you want to have a security class you inject, that can: Determine what permissions a user has. Determine if the required criteria is met. Let's reimagine your deletion function with DI and some separation of concerns: public function DeleteThreadFiles($threadId, $currentUser, $securityService, $fileService) { $thread = new ThreadModel($threadId); if ( !$securityService->userHasPermission($currentUser, 'can-delete-thread') || !$securityService->userHasPermission($currentUser, 'can-delete-own-thread' || $currentUser !== $thread->getOwner() ){ return false; } // Happy Path to delete foreach ($thread->getThreadFiles as $file) { $fileService->deleteFile($file); } } This shows how some code might be written that handles your envisioned functionality, where the owner AND a moderator or admin could delete a thread, and subsequently, have files deleted as well. General comment and suggestion Personally, I don't think you should be building in rendering into what is otherwise a persistence model class. These things have nothing to do with each other. Look at any sophisticated PHP app, and you will find a separation of concerns, where your "views" aka markup and look and feel is in templates. In your case, anytime you want to mess around with the markup, you will be changing a class that is primarily the "model". You could integrate a template component like twig, and immediately begin to take advantage of the many things twig does for you, not the least of which is structure and reuse of markup. If you really want hardwired button-type-x code, you can accomplish that in a variety of ways in twig without hardwiring it into a class where it doesn't belong.
  12. What specific component libraries are you using?
  13. Yes, the setting can be fixed with the double backslashes. This is because in windows the backslash is a separator for directory pathing, whereas in PHP it is used to escape characters in strings. With that said, this setting gets disabled entirely when you follow the inteliphense directions, because it is used in a disabled plugin. Get it "working" if you like but the setting isn't used, and you should probably just delete it entirely, and disable the plugins as I stated previously.
  14. PHPFreaks has been going through some ownership and hosting changes, and that has lead to some extended down time. The hosting for the site has been generously provided by a number of different people and organizations throughout the years, and without their patronage, phpfreaks would have shutdown many years ago. With that said, please understand that the volunteers who administer and moderate the site don't have control over the underlying infrastructure, other than what is provided to us. In this recent outage the new owner of the site, who supported it in the years following the sale of the original hosting company where phpfreaks was created, has provided us a lot of support and aid, and demonstrated a commitment to keep the site running for the foreseeable future. Unfortunately, with that said, there will probably be some additional outages in the near future as the server resources that run the site are being moved to a different co-location facility. Please bear with us through these difficulties, as we endeavor to keep the community alive and available for everyone who finds it useful. We will continue to keep doing the work to keep phpfreaks running, and we appreciate the many long time members who have made it their home.
  15. I would step back from what you have done so far, because it is fairly far away from what any ORM tries to do. What you have right now is a class that stores SQL. ORM's "build" sql statements. Since you are creating this from the ground up, one advantage you have is that you can control the database structure and naming of all tables and attributes. This allows you to write code that can take advantage of your table and column naming conventions. I would suggest you look at CakePHP for inspiration and clarity, as it has a simple but effective "ActiveRecord" type ORM, that starts with conventions which can be customized but don't need to be if your tables and columns were named using the CakePHP conventions. From the CakePHP Manual: One example of a convention is to have every table have its primary key named "id". If Table 'b' contains a foreign key for Table 'a' then that column will be named 'a_id'. If you follow these conventions, then you can write generic base class code that can generate the SQL join syntax you will need to do most things including making a join and storing associated entity data, in for example, a standard One-to-Many relationship. You will notice that CakePHP is based on 3 different base classes: Database This is where the DB specific configuration and connections are stored Table A Table has an associated Entity, which is your model mapping Handles querying (find) Has built in generic querying methods Custom queries can be added for a specific table Stores "joins" (Associations) Entity An entity is your table base class What you use to add a new row Allows you to add mutation code where a column needs some specialized conversion (ie. encryption/decryption) Allows you to define "virtual" columns (fullname = firstname + lastname) Some research that might help you: Learn what the ActiveRecord Pattern is. Go through the CakePHP code for Database and ORM in their Github repo. In particular look at the Database and ORM folders You will probably notice that just about every ORM has a query builder. These do the heavy lifting of allowing a developer to write code that can generate the underlying sql needed for even the most complicated queries. As Requinix already explained, this is complicated code. You need to figure out how to cut corners and simplify as much as possible, the types of queries you need. You also need to keep in mind that the point of the ORM is to abstract the underlying database into PHP Objects. ORM query classes allow the user to work directly with the objects in terms of queries. Doing anything close to that is a lot of work. So long as you avoid edge cases and complicated database design, you should be able to avoid having to get into that area, and rely instead on generic/base class code to handle the majority of the work you need to be done.
  16. Hello Marcus, So to be clear, what we are talking about is variable typing and type hints. Variable typing is only done within a class or trait. The dog class has examples of variable typing. I expanded the examples to make a point of what changed: <?php class Dog { private int $dog_weight = 0; private string $dog_breed = "no breed"; private string $dog_color = "no color"; private string $dog_name = "no name"; public function __construct($dog_weight, $dog_breed, $dog_color, $dog_name) { $this->dog_weight = $dog_weight; $this->dog_breed = $dog_breed; $this->dog_color = $dog_color; $this->dog_name = $dog_name; } public function get_properties() : string { return "$this->dog_weight, $this->dog_breed, $this->dog_color, $this->dog_name"; } } $fido = new Dog(42, 'Poodle', 'Brown', 'Fido'); echo $fido->get_properties() . PHP_EOL; $spike = new Dog('Heavy', 'Mutt', 'Orange', 'Spike'); // Generates Fatal error: Uncaught TypeError: Cannot assign string to property Dog::$dog_weight of type int echo $spike->get_properties() . PHP_EOL; The class variable definition lines like this one: "private int $dog_weight = 0" was first introduced in PHP 7.4. Prior to that you could not include the "int" to tell php you wanted $dog_weight to be a int. Furthermore, in my examples, if you try something like passing a string for the assignment, php will generate a runtime error now: "Fatal error: Uncaught TypeError: Cannot assign string to property Dog::$dog_weight of type int" Previously however, PHP did support type hinting for parameters that has a similar function. <?php class Dog { private $dog_weight = 0; private $dog_breed = "no breed"; private $dog_color = "no color"; private $dog_name = "no name"; public function __construct(int $dog_weight, string $dog_breed, string $dog_color, string $dog_name) { $this->dog_weight = $dog_weight; $this->dog_breed = $dog_breed; $this->dog_color = $dog_color; $this->dog_name = $dog_name; } public function get_properties() : string { return "$this->dog_weight, $this->dog_breed, $this->dog_color, $this->dog_name"; } } $fido = new Dog(42, 'Poodle', 'Brown', 'Fido'); echo $fido->get_properties() . PHP_EOL; $spike = new Dog('Heavy', 'Mutt', 'Orange', 'Spike'); // Generates a Fatal error: Uncaught TypeError: Dog::__construct(): Argument #1 ($dog_weight) must be of type int, string given echo $spike->get_properties() . PHP_EOL; This was available in PHP version 7.0. This parameter type hinting has been heavily used, especially when passing objects as parameters, since version 7.0. class Dog { private $dog_weight = 0; private $dog_breed = "no breed"; private $dog_color = "no color"; private $dog_name = "no name"; public function __construct(int $dog_weight, string $dog_breed, string $dog_color, string $dog_name) { $this->dog_weight = $dog_weight; $this->dog_breed = $dog_breed; $this->dog_color = $dog_color; $this->dog_name = $dog_name; } public function get_properties() : string { return "$this->dog_weight, $this->dog_breed, $this->dog_color, $this->dog_name"; } } class Cat { private $cat_breed = 'no breed'; private $cat_name = 'no name'; public function __construct(string $cat_breed, string $cat_name) { $this->cat_breed = $cat_breed; $this->cat_name= $cat_name; } public function get_properties() : string { return "$this->cat_breed, $this->cat_name"; } } class Kennel { private $borders = []; public function addDog(Dog $dog) : void { $this->borders[] = $dog; } public function getBorders() : string { $output = ''; foreach($this->borders as $pet) { $output .= $pet->get_properties() . PHP_EOL; } return $output; } } $kennel = new Kennel(); $fido = new Dog(42, 'Poodle', 'Brown', 'Fido'); $kennel->addDog($fido); $sparky = new Dog(22, 'Mutt', 'Tan', 'Sparky'); $kennel->addDog($sparky); $simba = new Cat('siamese', 'Simba'); echo $simba->get_properties() . PHP_EOL; echo $kennel->getBorders(); $kennel->addDog($simba); //Generates Fatal error: Uncaught TypeError: Kennel::addDog(): Argument #1 ($dog) must be of type Dog, Cat given What has never been possible is add a type to a variable declaration outside of a class definition (as you attempted to do): <?php int $errorCode = 7; //generates a Parse error: syntax error, unexpected '$errorCode' (T_VARIABLE) in 7. //generates Parse error: syntax error, unexpected variable "$errorCode" in 8. One other common type hint is to utilize an interface definition as a parameter type hint: <?php interface HasFeet { public function setFeet(int $number); public function getFeet() : int; } class Duck implements HasFeet { private $nbrFeet; public function setFeet(int $number) { $this->nbrFeet = $number; } public function getFeet() : int { return $this->nbrFeet; } } class Mouse implements HasFeet { private $legs; public function setFeet(int $number) { $this->legs = $number; } public function getFeet() : int { return $this->legs; } } class Fish { private $legs = 0; public function getFeet() : int { return $this->legs; } } class Catalog { private $animals = []; public function addAnimal(HasFeet $animal) { $this->animals[] = $animal; } public function getAnimalFeetCount() : string { $output = ''; foreach($this->animals as $animal) { $output .= 'A ' . get_class($animal) . " has {$animal->getFeet()} feet" . PHP_EOL; } return $output; } } $catalog = new Catalog(); $duck = new Duck(); $duck->setFeet(2); $mouse = new Mouse(); $mouse->setFeet(4); $catalog->addAnimal($duck); $catalog->addAnimal($mouse); echo $catalog->getAnimalFeetCount(); //Generates //A Duck has 2 feet //A Mouse has 4 feet // //Fatal error: Uncaught TypeError: Argument 1 passed to Catalog::addAnimal() must implement interface HasFeet, instance of Fish given PHP 8 has added constructor variable definition through parameter scope & typing: <?php // Prior to 8.0 - Standard class variable initialization class Bike { private $wheels = 0; public function __construct(int $wheels=2) { $this->wheels = $wheels; } public function getWheels() : int { return $this->wheels; } } // PHP 8.0 definition via parameter class Car { public function __construct(private int $wheels=4) { } public function getWheels() : int { return $this->wheels; } } $bike = new Bike(); echo $bike->getWheels() . PHP_EOL; $car = new Car(); echo $car->getWheels() . PHP_EOL; $truck = new Car(18); echo $truck->getWheels() . PHP_EOL; // In PHP 8.01+ // 2 // 4 // 18 So PHP 8 will relieve you of having to define attributes in the class definition, if you define them in the constructor. This works for class parameters as well!
  17. An Alias only affects the class it is defined in. If I alias a method with "MyTrait::foo as bar" then within that class you would need to use self::bar. Assuming this is in the definition of class A, then the original A::foo would be called. It's worth also noting that if the methods are public, trying to use a trait that has an overlap simply results in the non-inclusion of the trait. <?php trait Basic { public function whichFoo() { return 'basicFoo'; } } class Foo { use Basic; public function whichFoo() { return 'FooFoo'; } } $f = new Foo(); echo $f->whichFoo(); # outputs FooFoo I can see that you are trying to use these to handle relationships between doctrine entities, although I don't really know what these specific id methods are for, but I have to question your approach vs. a more traditional setup, given all the troubles you are having.
  18. I was just laying out the options. In your use case it seems like you would need to use the insteadof.
  19. In the PHP manual section Traits section. You have 2 options: Alias the conflicting method so it doesn't conflict Specify an "insteadof" method statement in the use section of the class
  20. The css and in some cases, html could use some improvement. You have a lot of wonky styling that could be improved. Just off the top of my head: Header/menu needs padding. Move Logo into header. Figure out typography All pages should have an h1 that matches the primary purpose/menu selection Home page menu is broken Header footer color is neon eye bleed green. I'd suggest you match your colors to your logo image. You can use a paint dropper app to figure out what those colors are. Images should be conformed to standard sizes. Scrimba has a bunch of free courses you can go through online to better learn html/css if you aren't sure of how you could make these changes to your existed pages and templates. https://scrimba.com/topic/free A few that would probably help you figure this out: Html & CSS Crash course (Kevin Powell) Learn Flexbox for free (Per Borgen) I've attached an image to help with these comments:
  21. There's a simple syntax error in the code you posted. The code uses the ternary operator. You have: print $dog_error_message ? 'Name update successful<br/> : 'Name update not successful<br/>'; Due to missing a single quote, you have broken the ternary. A ternary is in the form (boolean evaluation) ? (returned if true) : (returned if false) Fix your quotes like this: print $dog_error_message ? 'Name update successful<br/>' : 'Name update not successful<br/>';
  22. It looks to me like your kernel class is a quasi registry pattern class. It certainly has all the hallmarks of a Registry class in that it is a singleton, although typically the registry pattern also will only allow one instance of any of the objects it stores. Your kernel class is a singleton, but it looks like you replicated static public function getInstance() in every one of the classes you use, rather than inheriting that from a base class. That might have been the place to use a trait, but you'd be better off with a registry class. I will also point out that because a registry is a sort of global object container, it is seen as a bit of an anti-pattern, although it was certainly good enough for lots of Zend Framework 1.x applications in an earlier era. At this point, Dependency injection, and the use of a Dependency injection Container is the solution that frameworks like Symfony and Laravel use instead. You could implement one yourself, or use an existing DI Container. You might consider reading through the Symfony "Create your own framework" docs which includes discussion of how to utilize the symfony Dependency Injection container(DIC) component. You could also use PHP-DI. Both of these components have a lot of commonly desirable functions like autowiring, lazy loading and configuration via files or annotations. The weakness of a registry pattern for example, is that you have to make all those objects before you may even need all the services. With that said, if the most pragmatic solution for you is to use a registry, then I would suggest you more fully implement one. All your classes should not be hardwired to be instantiated statically -- just implement a $registry->set() and $registry->get(). Then you have something that can support other service objects you might need.
  23. So to summarize: You have some sort of Kinesiologist Platform as a service system? Or a business that is using this system internally? Is it actively in use, or was used in the past, but is now semi-functional? It's written in php and uses mysql It's "custom" but you aren't entirely sure what it might be based on, as you not an experienced php developer You need to add users to this Kinesiologist system, but you don't know how to accomplish that You need to create a "similar" CMS platform? Why is that? You can't figure out how to add a user to your existing system Or do you mean that you need add to the system you already have? What exactly are the specifications for things you want/need to add? There are a lot of different things you could do. The questions that remain are: What is your interest in the current system? Do you own it? Is it a business? Are you an employee assigned to manage or maintain? What level of a developer are you? Is there some reason you are not being totally forthcoming? To have any chance of helping we need specific details (code, db structure, possibly sample data) Are there reasons you can't/won't provide that? What do you think that anyone could do here to help you? We can't solve problems without being able to see code and database structure and possibly even data What advice do I have? You could and probably should, engage someone to help you understand your system and get you out of crisis mode This person should be a PHP, MySQL and system administration expert The current system might be 100% custom, or it could be based on a framework. If it is, you need someone who either has experience with that framework, or is good enough to figure out what they need to know
  24. You have to follow the phpinteliphense instructions and disable the builtin plugin.
  25. Those are not paths under windows. Under windows a path looks something like: C:\Program Files\php-8.1.2-Win32-vs16-x64 A Path to an actual file will be C:\Program Files\php-8.1.2-Win32-vs16-x64\php.exe 1st things 1st! You are using the Inteliphense plugin. If you navigate to the instructions it tells you to disable the builtin php Language Features extension. That setting points to a local cli php for linting. Inteliphense doesn't use that, so it doesn't matter. Disable the builtin and the message will go away. Based on what you've said you installed Laragon. Which version did you install? There is a full version and a portable version. There are really 2 forms of PHP. PHP in a webserver, that is handled for you by your Laragon install and the php CLI program that you would run in a command,cmd or powershell, and that I guess vscode wants a path to. You don't really need this to write code. With that said, most likely the path to your php is this: C:\laragon\bin\php\php-7.4.19-Win32-vc15-x64\php.exe Some things to understand: You don't need vscode integration to use it for PHP development. This is especially true if you're developing a web app. The php files just need to be in the right place so the webserver can process them. Laragon makes this structure for you: c:/laragon/www You can see this in the laragon app by clicking on the little gear, and it will be listed as the webroot. For your project(s) make a directory with Vscode inside that folder. Name it whatever you want but I would suggest not using spaces or non-ascii letters in your directory names, although you can. use Vscode's new directory button or menu choice to make your project folder inside c:/laragon/www. For this example, assume your folder is named "test" Once you have made this folder, open it as the project folder in Vscode Create a new folder named public Usually you want your webroot to be a directory beneath your project folder. There are a few different conventions, but /public is a common one. Create a new index.php file that just has this in it <?php phpinfo(); Navigate to it with your browser specifying the hostname of "localhost". If you get the php info page, then everything is working and you can now add/edit through vscode and should see your changes reflected in your browser. xdebug is hard to get working for many people For web development, again, in order for VSCode to be able to debug and make the connection between source files on your workstation and the programs running within the browser, you have to have everything configured perfectly or it won't work. You need a strong understanding of networking concepts and be able to configure the xdebug.ini appropriately for your system the xdebug extension has to be available, configure to work in your php environment, and have the right .ini settings For vscode you also need an xdebug plugin and the right settings You don't need xdebug to get started with php development. There are many other ways to debug your problems without an integrated debugger, even though it is a really nice tool to have for you in some situations. I rarely have felt like I really needed xdebug for day to day php development
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.