Jump to content

gizmola

Administrators
  • Posts

    6,060
  • Joined

  • Last visited

  • Days Won

    153

Everything posted by gizmola

  1. 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.
  2. 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
  3. You don't need to exit from a php script. exit and die are the same function. You use them in functions/methods.
  4. 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.
  5. 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.
  6. What specific component libraries are you using?
  7. 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.
  8. 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.
  9. 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.
  10. 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!
  11. 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.
  12. I was just laying out the options. In your use case it seems like you would need to use the insteadof.
  13. 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
  14. 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:
  15. 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/>';
  16. 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.
  17. 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
  18. You have to follow the phpinteliphense instructions and disable the builtin plugin.
  19. 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
  20. Welcome to PHPF! Please use the <> button to paste in code in the future. I editted your original post to do that for you this time. Your code is using several namespaced classes, but it is missing any statements that might require or include or autoload those classes. The names are very generic, so it's hard to know for sure what they might be a part of. They are not soap specific, as it is just using a generic http request class to send a request that has a soap document embedded in it. You would expect to receive a response that had a soap document inside of it, if it actually worked. My advice to you would be to use one of the many http libraries and just replace those calls with the ones from the library. You will need to have composer installed on your workstation, and hopefully you'll be able to figure out how to use it to install the http client and make a couple small changes to replace the missing libraries. My suggestion would be to use Guzzle, mainly because it is the best known/longstanding PHP library of its type. First off make sure you have composer installed (globally) on your machine. In other words, follow the instructions to install it so it can be used anywhere rather than just installing it in your project directory. Make yourself a new subdirectory. Open a terminal and cd to that directory. Then run this: composer require guzzlehttp/guzzle You probably need a github account, and you may have to create a github personal access token and install it in composer. Try to do the composer require without installing the token, but set it if you get any errors. If you do need the token, make one for 90 days. The default settings are readonly, and those are fine for what you need, which is just to be able to have composer get any component libraries you might want to use. In Github, when you create a token, it will show it to you and you can copy it to your clipboard. Then you would run this command in the terminal: composer config --global --auth github-oauth.github.com token_pasted_here At that point you should have no issues with the composer require command. It will download Guzzle libs into a vendor directory, create a composer.json file for your project, and also create an autoloader you will include. At this point, you can take the code you were provided, and make a new version of it in the root of your project directory. I named this file soaprequest.php, but the file name doesn't matter. I went ahead and ported your code to a guzzle version. You will need to change the specific url and any token information required, as when I ran it as a test I got a 404 response for the url, so I couldn't probe further. <?php // soaprequest.php require("vendor/autoload.php"); $client = new GuzzleHttp\Client([ 'base_uri' => 'https://divaltosainteroseline.coaxis.com/WebServiceDiva', 'timeout' => 5.0, 'headers' => ['accept-encoding' => 'gzip', 'content-type' => 'text/xml'] ]); $body = '<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <WebServiceDiva xmlns="http://www.Divalto.fr/WebService/"> <action>&lt;action&gt;WP_CREATECLI</action> <param> {licence:"XXXXX=",client: {"dos":"2","nom":"Alex Xela","adr1":"53 Bd Carnot","adr2":"","adr3":"","adr4":"","cpostal":"06400","vil":"Cannes","tel":"053837979","email":"[email protected]","siret":"","naf":"","regcod":"CB","tvatie":"0","catclicod":"","tacod":"","tarcod":"","blmod":"DPD","texcod1":"","texcod2":"","texcod3":"","texcod4":"","tvano":"","visa":"2"},adresse: {"nom":"Alex Xela","adr1":"53 Bd Carnot","adr2":"","adr3":"","adr4":"","cpostal":"06400","ville":"","tel":"053837979","email":"[email protected]","livprincipale":"2","facprincipale":""},contact: {"contact":"Customer","nom":"Alex Xela","prenom":"","tit":"","lib":"","tel":"","telgsm":"","fax":"","email":"[email protected]","servcod":"","fctcod":""},banque: {"ribcod":"","ribdo":"","iban1":"","iban2":"","iban3":""}} </param> </WebServiceDiva> </soap:Body> </soap:Envelope>'; try { $response = $client->request('POST', '/WebServiceDiva.asmx', ['body' => $body]); echo "Successful request" . PHP_EOL; $responseBody = $response->getBody(); echo $responseBody; } catch (ClientException $e) { echo Psr7\Message::toString($e->getRequest()); echo Psr7\Message::toString($e->getResponse()); } Again from the terminal, you will run this in the root directory of your project: php -f soaprequest.php It will output any errors or the response from the soap server to the screen in the terminal. If you actually get a response, then you might want to load that data into an object using simplexml or possibly use a soap library, but the code you started with did none of those things.
  21. There are a few different ways to do this, but all of them have a significant learning curve. You really need to understand HTTP, and all the basics of HTML structure, forms, downloads etc. The first path would be to use a Functional testing tool. One long standing open source tool I can point you to would be Selenium, and in particular Selenium IDE. What you do with this tool is record your interaction using their browser extension tool, and then use that script to perform your job afterwards. I'm not a QA automation expert, but this is the basic idea behind how companies put together testing for their websites. I included a short introduction video to give you an idea. There are some additional details you would need, that are probably OS dependent, as to how you would schedule and invoke the selenium test. PHP has tooling that will let you run selenium tests via PHP scripting. The 2nd path would be to use an HTTP client library. Basically, you write PHP code that simulates a web client session for you. Again, these tools are often used for QA automated testing, but there are also many other use cases, like serverside integration with outside API's. Curl as you mentioned, is sometimes an enabling technology in these client libraries, and you certainly could write curl code directly using the curl library, but the client libraries do tend to be easier to work with, and offer classes that hide complexity. There are numerous client libraries you could look at but I'll provide 3 for your consideration: Symfony HTTP Client Guzzle 7 Buzz I'm a big fan of the Symfony components, as is a lot of the PHP developer community. Guzzle is probably the most used Client library, and has excellent documentaion. Buzz is perhaps a little more terse and simpler. It was created by a well known symfony contributor. I pointed you to the github project. To get a feel for it, navigate to the docs folder in github, and there you will find the documentation. Some videos that might help: Guzzle walk through based on an article. This guy wrote an article, and on his windows machine walks through the article and demonstrates the things in the article. There is no actual voice over narrative, so it's just watching what he's doing, but that might be of help to you especially if you are on windows. He uses VSCode which is a good choice if you're new to modern PHP development. Gary Clarke has a lot of really good PHP development videos. He walks through using the Symfony HTTP client in this series. The one thing you have to understand is that he is a proponent of TDD (Test Driven Development) where you write unit tests first, and then develop your code to meet the criteria of the tests. It's a really interesting way of developing code that has a lot of proponents, but there are more moving parts to it. I still think it's an interesting watch that you might learn some things from:
  22. How about the official Docs: https://code.visualstudio.com/docs Once setup ok, go through these short "microsoft recommended" videos. https://code.visualstudio.com/docs/getstarted/introvideos They are all pretty short and go over the basics. I reviewed enough of this video tutorial to know that it is clear, concise and well presented, and doesn't suffer from the issues you described in some previous videos you might have seen previously. You might consider giving it a shot. It was made by a guy who worked on the official Python extension at Microsoft, so he really knows the editor very well.
  23. Please use code tags <>. Basically you need to make up your mind as to what this script is intended to do: Return the data for an image, so that it can be referenced as the source in an image tag. Return Some html The problem you have right now is that you are setting the header, as if you wanted to return image data header ('Content-Type: image/png'); Then you return some html, which includes an img tag and an embedded base64 image. echo '<img src="data:image;base64, ' .$im. '" style="width:5in;height:5in;">'; So, if you want to return the data and reference the script in an <img src="..."> tag, then you would continue to use the header (as long as your image is actually going to be a .png) and just return the image data. Often this is what people want to do, when creating an image on the fly in the server. In your case, you started with some base64 data, that is perhaps an image. If so, then all your existing code would need is this // header ('Content-Type: image/png'); --NO! You are returning HTML not image data $b64 = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; echo '<img src="data:image/png;base64, ' . $b64 . '" style="width:5in;height:5in;">'; Amongst the several confusing mistakes you are making currently, you read data into a GD OBJECT. Then you try and return that object in a place where you need base64 encoded data. If you are going to use a function, you need to actually take 30 seconds and look up the function and at minimum: Check the number and types of the parameters Check what the function returns I'm going to assume here that there is some reason you want to read image data into GD. In this case, you commented out all the code that you would need to actually have this function. At minimum it would be more like this: // header ('Content-Type: image/png'); --NO! You are returning HTML not image data $b64 = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; $bin = base64_decode($b64); // Load GD resource from binary data $im = imageCreateFromString($bin); if (!$im) { die('Base64 value is not a valid image'); } echo '<img src="data:image/png;base64, ' . base64_encode(imagepng($im)) . '" style="width:5in;height:5in;">'; This is unsophisticated code, because it has the baked in assumption that your original source is the base64 encoded version of a .png image.
  24. $data is an array with one element that is an array. That array has a lot of elements including the one you say you want. So try: <?php foreach ($data[0]['lastData'] as $key => $key_value) { echo "key: $key, value: $key_value <br>"; } Once you have figured out which keys you actually want, you should be able to access them more directly. So for example: echo "<p>Temperature (F): {$data[0]['lastData']['tempinf']}</p>"; echo "<p>Wind (mph): {$data[0]['lastData']['windspeedmph']}</p>"; I don't see a min/max temp value in the data you provided. Aside from 'lastData', there are several other keys and nested arrays in some cases. For figuring this out in the future, aside from var_dump, print_r is often a useful development/debugging function that can be used as an alternative.
  25. Maybe one of your validations failed, and it set a value in $this->error_array. You check if that's empty, but if it isn't, you just return false, so the value of that array is set to something you don't make that visible. You should probably have a method to return it. class Account { // current code public function getValidationErrors() { return $this->error_array; } } And then your code could be something like: if($account->UpdateDetails($firstName,$lastName,$email,$userLoggedin)){ //Sucess echo "update"; } else { ///failure echo "No update"; echo '<pre>' . explode(PHP_EOL, $account->getValidationErrors()) . '</pre>'; }
×
×
  • 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.